diff --git a/README.md b/README.md index 4e099caf..c1ed83c1 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ ## A Three.js wrapper for GWT # Maven -Current Version 0.107, implements 0.107 version of three.js +Current Version 0.108, implements 0.108 version of three.js ```xml org.treblereel.gwt three4g - 0.107 + 0.108-SNAPSHOT ``` # Setup diff --git a/annotations/pom.xml b/annotations/pom.xml index c98ceedc..5c8a23ed 100644 --- a/annotations/pom.xml +++ b/annotations/pom.xml @@ -5,7 +5,7 @@ org.treblereel.gwt three4g-parent - 0.108-SNAPSHOT + 0.109-SNAPSHOT .. diff --git a/core/pom.xml b/core/pom.xml index e3667d9f..b740c0fe 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ org.treblereel.gwt three4g-parent - 0.108-SNAPSHOT + 0.109-SNAPSHOT .. diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/AnimationLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/AnimationLoader.java index 5734fb68..388601d4 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/AnimationLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/AnimationLoader.java @@ -1,6 +1,5 @@ package org.treblereel.gwt.three4g.loaders; -import com.google.gwt.json.client.JSONObject; import jsinterop.annotations.JsConstructor; import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.animation.AnimationClip; @@ -8,17 +7,11 @@ /** * Class for loading AnimationClips in JSON format. This uses the FileLoader internally for loading files. - * * @author Dmitrii Tikhomirov * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class AnimationLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; +public class AnimationLoader extends Loader { @JsConstructor public AnimationLoader() { @@ -29,57 +22,4 @@ public AnimationLoader() { public AnimationLoader(LoadingManager manager) { } - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - - /** - * Parse the JSON object and pass the result to onLoad. Individual clips in the object will be parsed with AnimationClip.parse. - * - * @param json — required - * @param onLoad — Will be called when parsing completes. - */ - public native void parse(JSONObject json, OnLoadCallback onLoad); //TODO checkit - - /** - * Sets the base path or URL from which to load files. This can be useful if - * you are loading many animations from the same directory. - * - * @param path — Base path of the file to load. - * @return instance of AnimationLoader - */ - public native AnimationLoader setPath(String path); } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/AudioLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/AudioLoader.java index 2a2773bc..c8a55805 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/AudioLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/AudioLoader.java @@ -12,12 +12,7 @@ * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class AudioLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; +public class AudioLoader extends Loader { @JsConstructor public AudioLoader() { @@ -25,56 +20,8 @@ public AudioLoader() { } @JsConstructor - public AudioLoader(String context) { - - } - - @JsConstructor - public AudioLoader(String context, LoadingManager manager) { + public AudioLoader(LoadingManager manager) { } - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - /** - * Sets the base path or URL from which to load files. This can be useful if you are loading many audios from the same directory. - * - * @param path — Base path of the file to load. - * @return instance of AudioLoader - */ - public native AudioLoader setPath(String path); - } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/BufferGeometryLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/BufferGeometryLoader.java index 2bd221c9..76efa357 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/BufferGeometryLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/BufferGeometryLoader.java @@ -7,17 +7,11 @@ /** * A loader for loading a BufferGeometry. This uses the FileLoader internally for loading files. - * * @author Dmitrii Tikhomirov * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class BufferGeometryLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; +public class BufferGeometryLoader extends Loader { @JsConstructor public BufferGeometryLoader() { @@ -28,56 +22,4 @@ public BufferGeometryLoader() { public BufferGeometryLoader(LoadingManager manager) { } - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - /** - * Parse a JSON structure and return a BufferGeometry. - * - * @param json — The JSON structure to parse. - * @return instance of BufferGeometry - */ - public native BufferGeometry parse(String json); - - /** - * Sets the base path or URL from which to load files. This can be useful if - * you are loading many geometries from the same directory. - * - * @param path — Base path of the file to load. - * @return instance of BufferGeometryLoader - */ - public native BufferGeometryLoader setPath(String path); } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/CompressedTextureLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/CompressedTextureLoader.java index 513a0345..396ff2f6 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/CompressedTextureLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/CompressedTextureLoader.java @@ -4,21 +4,10 @@ /** * Abstract base class for block based textures loader (dds, pvr, ...). This uses the FileLoader internally for loading files. - * * @author Dmitrii Tikhomirov * Created by treblereel on 10/9/18. */ -public abstract class CompressedTextureLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; - - /** - * The base path from which files will be loaded. See .setPath. Default is undefined. - */ - public String path; +public abstract class CompressedTextureLoader extends Loader { /** * Creates a new CompressedTextureLoader. @@ -29,53 +18,9 @@ public CompressedTextureLoader() { /** * Creates a new CompressedTextureLoader. - * * @param manager — The loadingManager for the loader to use. Default is THREE.DefaultLoadingManager. */ public CompressedTextureLoader(LoadingManager manager) { } - - /** - * Begin loading from url and pass the loaded texture to onLoad. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Begin loading from url and pass the loaded texture to onLoad. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Begin loading from url and pass the loaded texture to onLoad. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - - /** - * Begin loading from url and pass the loaded texture to onLoad. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - /** - * Set the base path or URL from which to load files. This can be useful if you are loading many models from the same directory. - * - * @param path base path or URL - * @return instance of FileLoader - */ - public native T setPath(String path); } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/CubeTextureLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/CubeTextureLoader.java index 1b9c16a6..19d26db0 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/CubeTextureLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/CubeTextureLoader.java @@ -7,27 +7,11 @@ /** * Class for loading a CubeTexture. This uses the ImageLoader internally for loading files. - * * @author Dmitrii Tikhomirov * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class CubeTextureLoader { - - /** - * If set, assigns the crossOrigin attribute of the image to the value of crossOrigin, prior to starting the load. Default is anonymous. - */ - public String crossOrigin; - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; - - /** - * The base path from which files will be loaded. See .setPath. Default is undefined. - */ - public String path; +public class CubeTextureLoader extends Loader { @JsConstructor public CubeTextureLoader() { @@ -40,40 +24,39 @@ public CubeTextureLoader(LoadingManager manager) { } /** - * @param urls — array of 6 urls to images, one for each side of the CubeTexture. The urls should be specified in the following order: pos-x, neg-x, pos-y, neg-y, pos-z, neg-z. They can also be Data URIs. - * Note that, by convention, cube maps are specified in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, using a left-handed coordinate system. Since three.js uses a right-handed coordinate system, environment maps used in three.js will have pos-x and neg-x swapped. - * @return instance of CubeTexture + * Begin loading from url and call onLoad with the response content. + * @param url — A string containing the path/URL of the file. */ - public native CubeTexture load(String[] urls); - - - /** - * @param urls — array of 6 urls to images, one for each side of the CubeTexture. The urls should be specified in the following order: pos-x, neg-x, pos-y, neg-y, pos-z, neg-z. They can also be Data URIs. - * Note that, by convention, cube maps are specified in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, using a left-handed coordinate system. Since three.js uses a right-handed coordinate system, environment maps used in three.js will have pos-x and neg-x swapped. - * @param onLoad — Will be called when load completes. The argument will be the loaded texture. - */ - public native void load(String[] urls, OnLoadCallback onLoad); - + public native CubeTexture load(String[] url); /** - * @param urls — array of 6 urls to images, one for each side of the CubeTexture. The urls should be specified in the following order: pos-x, neg-x, pos-y, neg-y, pos-z, neg-z. They can also be Data URIs. - * Note that, by convention, cube maps are specified in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, using a left-handed coordinate system. Since three.js uses a right-handed coordinate system, environment maps used in three.js will have pos-x and neg-x swapped. - * @param onLoad — Will be called when load completes. The argument will be the loaded texture. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .total and .loaded bytes. - * @param onError — Will be called when load errors. + * Begin loading from url and call onLoad with the response content. + * @param url — A string containing the path/URL of the file. + * @param onLoad — A function to be called after loading is successfully completed. The function + * receives the loaded SVGDocument as an argument. */ - public native void load(String[] urls, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); + public native void load(String[] url, OnLoadCallback onLoad); /** - * Set the crossOrigin attribute. - * - * @param origin crossOrigin attribute + * Begin loading from url and call onLoad with the response content. + * @param url — A string containing the path/URL of the file. + * @param onLoad — A function to be called after loading is successfully completed. The function + * receives the loaded SVGDocument as an argument. + * @param onProgress — A function to be called while the loading is in progress. The argument will + * be the XMLHttpRequest instance, which contains total and loaded bytes. */ - public native void setCrossOrigin(String origin); + public native void load(String[] url, OnLoadCallback onLoad, OnProgressCallback onProgress); /** - * @param path Set the base path or URL from which to load files. This can be useful if you are loading many textures from the same directory. - * @return instance of FileLoader + * Begin loading from url and call onLoad with the response content. + * @param url — A string containing the path/URL of the file. + * @param onLoad — A function to be called after loading is successfully completed. The function + * receives the loaded SVGDocument as an argument. + * @param onProgress — A function to be called while the loading is in progress. The argument will + * be the XMLHttpRequest instance, which contains total and loaded bytes. + * @param onError — A function to be called if an error occurs during loading. The function + * receives the error as an argument. */ - public native CubeTextureLoader setPath(String path); + public native void load( + String url[], OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/DataTextureLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/DataTextureLoader.java index c3826e6c..78f5f842 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/DataTextureLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/DataTextureLoader.java @@ -5,21 +5,10 @@ /** * Abstract base class to load generic binary textures formats (rgbe, hdr, ...). * This uses the FileLoader internally for loading files, and creates a new DataTexture. - * * @author Dmitrii Tikhomirov * Created by treblereel on 10/9/18. */ -public abstract class DataTextureLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; - - /** - * The base path from which files will be loaded. See .setPath. Default is undefined. - */ - public String path; +public abstract class DataTextureLoader extends Loader { /** * Creates a new CompressedTextureLoader. @@ -30,53 +19,9 @@ public DataTextureLoader() { /** * Creates a new CompressedTextureLoader. - * * @param manager — The loadingManager for the loader to use. Default is THREE.DefaultLoadingManager. */ public DataTextureLoader(LoadingManager manager) { } - - /** - * Begin loading from url and pass the loaded texture to onLoad. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Begin loading from url and pass the loaded texture to onLoad. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Begin loading from url and pass the loaded texture to onLoad. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - - /** - * Begin loading from url and pass the loaded texture to onLoad. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - /** - * Set the base path or URL from which to load files. This can be useful if you are loading many models from the same directory. - * - * @param path base path or URL - * @return instance of a Loader - */ - public native T setPath(String path); } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/FileLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/FileLoader.java index 0d402cc5..a790e4d3 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/FileLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/FileLoader.java @@ -1,8 +1,8 @@ package org.treblereel.gwt.three4g.loaders; +import elemental2.dom.File; import jsinterop.annotations.JsConstructor; import jsinterop.annotations.JsType; -import org.treblereel.gwt.three4g.core.PropertyHolder; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; /** @@ -13,33 +13,17 @@ * Cache.enabled = true; This is a global property and only needs to be set once to be used by all loaders that use * FileLoader internally. Cache is a cache module that holds the response from each request made through this loader, * so each file is requested once. - * * @author Dmitrii Tikhomirov * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class FileLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; +public class FileLoader extends Loader { /** * The expected mimeType. See .setMimeType. Default is undefined. */ public String mimeType; - /** - * The base path from which files will be loaded. See .setPath. Default is undefined. - */ - public String path; - - /** - * The request header used in HTTP request. See .setRequestHeader. Default is undefined. - */ - public Object requestHeader; - /** * The expected response type. See .setResponseType. Default is undefined. */ @@ -60,64 +44,13 @@ public FileLoader(LoadingManager loadingManager) { } - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - /** * Set the expected mimeType of the file being loaded. Note that in many cases this will be determined automatically, so by default it is undefined. - * * @param mimeType as String value * @return instance of FileLoader */ public native FileLoader setMimeType(String mimeType); - /** - * Set the base path or URL from which to load files. This can be useful if you are loading many models from the same directory. - * - * @param path base path or URL - * @return instance of FileLoader - */ - public native FileLoader setPath(String path); - - /** - * Set the request header used in HTTP request. - * - * @param requestHeader - key: The name of the header whose value is to be set. value: The value to set as the body of the header. - * @return instance of FileLoader - */ - public native FileLoader setRequestHeader(Object requestHeader); - /** * Change the response type. Valid values are: * text or empty string (default) - returns the data as string. @@ -125,7 +58,6 @@ public FileLoader(LoadingManager loadingManager) { * blob - returns the data as a Blob. * document - parses the file using the DOMParser. * json - parses the file using JSON.parse. - * * @param responseType type of type * @return instance of FileLoader */ @@ -134,11 +66,8 @@ public FileLoader(LoadingManager loadingManager) { /** * Whether the XMLHttpRequest uses credentials such as cookies, authorization headers or TLS client certificates. See XMLHttpRequest.withCredentials. * Note that this has no effect if you are loading files locally or from the same domain. - * * @param value if true, use credentials * @return instance of FileLoader */ public native FileLoader setWithCredentials(boolean value); - - } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/FontLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/FontLoader.java index 36c59116..d5493706 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/FontLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/FontLoader.java @@ -1,6 +1,5 @@ package org.treblereel.gwt.three4g.loaders; -import com.google.gwt.json.client.JSONObject; import jsinterop.annotations.JsConstructor; import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.extras.core.Font; @@ -10,77 +9,19 @@ * Class for loading a font in JSON format. Returns a Font, which is an array of Shapes representing the font. This uses the FileLoader internally for loading files. *

* You can convert fonts online using facetype.js - * * @author Dmitrii Tikhomirov * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class FontLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; - - /** - * The base path from which files will be loaded. See .setPath. Default is undefined. - */ - public String path; - +public class FontLoader extends Loader { @JsConstructor - public FontLoader(){ + public FontLoader() { } @JsConstructor - public FontLoader(LoadingManager manager){ + public FontLoader(LoadingManager manager) { } - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - - public native Font parse (String json); - - /** - * Set the base path or URL from which to load files. This can be useful if you are loading many models from the same directory. - * - * @param path base path or URL - * @return instance of FileLoader - */ - public native FontLoader setPath(String path); } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/ImageBitmapLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/ImageBitmapLoader.java index d4962051..97ed915a 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/ImageBitmapLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/ImageBitmapLoader.java @@ -8,22 +8,11 @@ /** * A loader for loading an Image as an ImageBitmap. An ImageBitmap provides an asynchronous and resource efficient pathway * to prepare textures for rendering in WebGL. - * * @author Dmitrii Tikhomirov * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class ImageBitmapLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; - - /** - * The base path from which files will be loaded. See .setPath. Default is undefined. - */ - public String path; +public class ImageBitmapLoader extends Loader { /** * An optional object that sets options for the internally used createImageBitmap factory method. Default is undefined. @@ -40,72 +29,10 @@ public ImageBitmapLoader(LoadingManager manager) { } - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - /** - * Given a URL, uses the URL modifier callback (if any) and returns a resolved URL. If no URL modifier is set, returns - * the original URL. - * - * @param url — the url to load - * @return resulting url - */ - public native String resolveURL(String url); - - /** - * Set the .crossOrigin attribute. - * - * @param origin attribute - * @return instance of ImageBitmapLoader - */ - public native ImageBitmapLoader setCrossOrigin(String origin); - - /** - * Set the base path or URL from which to load files. This can be useful if you are loading many textures from the same directory. - * @param path base path or URL - * @return instance of ImageBitmapLoader - */ - public native ImageBitmapLoader setPath(String path); - /** * Sets the options object for createImageBitmap. - * * @param options object * @return instance of ImageBitmapLoader */ public native ImageBitmapLoader setOptions(String options); - - } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/ImageLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/ImageLoader.java index 1fc822a8..d0c24845 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/ImageLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/ImageLoader.java @@ -8,85 +8,19 @@ /** * A loader for loading an Image. This uses the FileLoader internally for loading files, and is used internally by the * CubeTextureLoader, ObjectLoader and TextureLoader. - * * @author Dmitrii Tikhomirov * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class ImageLoader { - - /** - * If set, assigns the crossOrigin attribute of the image to the value of crossOrigin, prior to starting the load. Default is anonymous. - */ - public String crossOrigin; - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; - - /** - * The base path from which files will be loaded. See .setPath. Default is undefined. - */ - public String path; +public class ImageLoader extends Loader { @JsConstructor - public ImageLoader(){ + public ImageLoader() { } @JsConstructor - public ImageLoader(LoadingManager manager){ + public ImageLoader(LoadingManager manager) { } - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - - /** - * Load the URL and pass the response to the onLoad function. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when loading completes. The argument will be the loaded response. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest - * @param onError — Will be called if an error occurs. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - /** - * Set the .crossOrigin attribute. - * @param origin crossOrigin attribute. - * @return ImageLoader - */ - public native ImageLoader setCrossOrigin(String origin); - - /** - * Set the base path or URL from which to load files. This can be useful if you are loading many textures from the same directory. - * @param path base path or URL - * @return instance of FileLoader - */ - public native ImageLoader setPath(String path); - } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/AbstractLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/Loader.java similarity index 60% rename from core/src/main/java/org/treblereel/gwt/three4g/loaders/AbstractLoader.java rename to core/src/main/java/org/treblereel/gwt/three4g/loaders/Loader.java index 10b749c1..91a9c05b 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/AbstractLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/Loader.java @@ -1,17 +1,52 @@ package org.treblereel.gwt.three4g.loaders; import jsinterop.annotations.JsType; +import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; /** @author Dmitrii Tikhomirov Created by treblereel on 10/9/18. */ -@JsType(isNative = true) -public abstract class AbstractLoader { +@JsType(isNative = true, namespace = "THREE") +public abstract class Loader { + + /** + * The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS. Default is anonymous. + */ + public String crossOrigin ; + + /** + * The loadingManager the loader is using. Default is DefaultLoadingManager. + */ + public LoadingManager manager; + + /** + * The base path from which the asset will be loaded. Default is the empty string. + */ + public String path; + + /** + * The request header used in HTTP request. See .setRequestHeader. Default is empty object. + */ + public Object requestHeader; + + /** + * The base path from which additional resources like textures will be loaded. Default is the empty string. + */ + public String resourcePath; + + + public Loader() { + + } + + public Loader(LoadingManager manager) { + + } /** * Begin loading from url and call onLoad with the response content. * * @param url — A string containing the path/URL of the file. */ - public native void load(String url); + public native V load(String url); /** * Begin loading from url and call onLoad with the response content. @@ -20,7 +55,7 @@ public abstract class AbstractLoader { * @param onLoad — A function to be called after loading is successfully completed. The function * receives the loaded SVGDocument as an argument. */ - public native void load(String url, OnLoadCallback onLoad); + public native V load(String url, OnLoadCallback onLoad); /** * Begin loading from url and call onLoad with the response content. @@ -31,7 +66,7 @@ public abstract class AbstractLoader { * @param onProgress — A function to be called while the loading is in progress. The argument will * be the XMLHttpRequest instance, which contains total and loaded bytes. */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); + public native V load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); /** * Begin loading from url and call onLoad with the response content. @@ -44,7 +79,7 @@ public abstract class AbstractLoader { * @param onError — A function to be called if an error occurs during loading. The function * receives the error as an argument. */ - public native void load( + public native V load( String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); /** @@ -53,7 +88,7 @@ public native void load( * @param origin crossOrigin attribute * @return instance of T */ - public native T setCrossOrigin(String origin); + public native L setCrossOrigin(String origin); /** * Set the base path for additional resources. @@ -61,7 +96,7 @@ public native void load( * @param path — Base path for loading additional resources e.g. textures and .bin data. * @return instance of T */ - public native T setPath(String path); + public native L setPath(String path); /** * Set base path for additional resources like textures. If set, this path will be used as the @@ -70,5 +105,12 @@ public native void load( * @param path — required * @return instance of T */ - public native T setResourcePath(String path); + public native L setResourcePath(String path); + + /** + * + * @param requestHeader - key: The name of the header whose value is to be set. value: The value to set as the body of the header. + * @return instance of Loader + */ + public native L setRequestHeader(Object requestHeader); } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/MaterialLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/MaterialLoader.java index 4952ab93..a5818090 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/MaterialLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/MaterialLoader.java @@ -1,6 +1,5 @@ package org.treblereel.gwt.three4g.loaders; -import com.google.gwt.json.client.JSONObject; import jsinterop.annotations.JsConstructor; import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; @@ -9,17 +8,11 @@ /** * A loader for loading a Material in JSON format. This uses the FileLoader internally for loading files. - * * @author Dmitrii Tikhomirov * Created by treblereel on 4/26/18. */ @JsType(isNative = true, namespace = "THREE") -public class MaterialLoader { - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; +public class MaterialLoader extends Loader { /** * Object holding any textures used by the material. See .setTextures. @@ -36,60 +29,10 @@ public MaterialLoader(LoadingManager loadingManager) { } - /** - * Begin loading from url and return the Material object that will contain the data. - * - * @param url — the path or URL to the file. This can also be a Data URI. - */ - public native void load(String url); - - /** - * Begin loading from url and return the Material object that will contain the data. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when load completes. The argument will be the loaded Material. - */ - public native void load(String url, OnLoadCallback onLoad); - - /** - * Begin loading from url and return the Material object that will contain the data. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when load completes. The argument will be the loaded Material. - * @param onProgress — Will be called while load progresses. The argument will be the progress event. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - /** - * Begin loading from url and return the Material object that will contain the data. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when load completes. The argument will be the loaded Material. - * @param onProgress — Will be called while load progresses. The argument will be the progress event. - * @param onError — Will be called when load errors. - */ - public native void load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - /** - * Parse a JSON structure and create a new Material of the type json.type with parameters defined in the json object. - * - * @param json — The json object containing the parameters of the Material. - * @return instance of Material - */ - public native Material parse(JSONObject json); - /** * @param textures — object containing any textures used by the material. * @return instance of MaterialLoader */ public native MaterialLoader setTextures(Texture[] textures); - /** - * Sets the base path or URL from which to load files. This can be useful if you are loading many materials from the same directory. - * - * @param path — Base path of the file to load. - * @return instance of MaterialLoader - */ - public native MaterialLoader setPath(String path); - } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/loaders/TextureLoader.java b/core/src/main/java/org/treblereel/gwt/three4g/loaders/TextureLoader.java index a78055d7..865b4c73 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/loaders/TextureLoader.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/loaders/TextureLoader.java @@ -7,33 +7,11 @@ /** * Class for loading a texture. This uses the ImageLoader internally for loading files. - * * @author Dmitrii Tikhomirov * Created by treblereel on 3/5/18. */ @JsType(isNative = true, namespace = "THREE") -public class TextureLoader { - - /** - * If set, assigns the crossOrigin attribute of the image to the value of crossOrigin, prior to starting the load. Default is anonymous. - */ - public String crossOrigin; - - /** - * The loadingManager the loader is using. Default is DefaultLoadingManager. - */ - public LoadingManager manager; - - /** - * The base path from which files will be loaded. See .setPath. Default is undefined. - */ - public String path; - - /** - * Whether the XMLHttpRequest uses credentials - see .setWithCredentials. Default is undefined. - */ - public String withCredentials; - +public class TextureLoader extends Loader { /** * Creates a new TextureLoader. @@ -45,77 +23,10 @@ public TextureLoader() { /** * Creates a new TextureLoader. - * * @param manager — The loadingManager for the loader to use. Default is DefaultLoadingManager. */ @JsConstructor public TextureLoader(LoadingManager manager) { } - - /** - * Begin loading from the given URL and pass the fully loaded texture to onLoad. The method also returns a new texture - * object which can directly be used for material creation. If you do it this way, the texture may pop up in your scene - * once the respective loading process is finished. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @return Texture - */ - public native Texture load(String url); - - /** - * Begin loading from the given URL and pass the fully loaded texture to onLoad. The method also returns a new texture - * object which can directly be used for material creation. If you do it this way, the texture may pop up in your scene - * once the respective loading process is finished. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when load completes. The argument will be the loaded texture. - *

- * @return Texture - */ - public native Texture load(String url, OnLoadCallback onLoad); - - /** - * Begin loading from the given URL and pass the fully loaded texture to onLoad. The method also returns a new texture - * object which can directly be used for material creation. If you do it this way, the texture may pop up in your scene - * once the respective loading process is finished. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when load completes. The argument will be the loaded texture. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .total and .loaded bytes. - *

- * @return Texture - */ - public native Texture load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress); - - /** - * Begin loading from the given URL and pass the fully loaded texture to onLoad. The method also returns a new texture - * object which can directly be used for material creation. If you do it this way, the texture may pop up in your scene - * once the respective loading process is finished. - * - * @param url — the path or URL to the file. This can also be a Data URI. - * @param onLoad — Will be called when load completes. The argument will be the loaded texture. - * @param onProgress — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .total and .loaded bytes. - * @param onError — Will be called when load errors. - *

- * @return Texture - */ - public native Texture load(String url, OnLoadCallback onLoad, OnProgressCallback onProgress, OnErrorCallback onError); - - /** - * Set the .crossOrigin attribute. - * - * @param value crossOrigin attribute - */ - public native void setCrossOrigin(String value); - - - /** - * Set the base path or URL from which to load files. This can be useful if you are loading many models from the same directory. - * - * @param path base path or URL - * @return instance of TextureLoader - */ - public native TextureLoader setPath(String path); - } diff --git a/core/src/main/java/org/treblereel/gwt/three4g/materials/MeshPhysicalMaterial.java b/core/src/main/java/org/treblereel/gwt/three4g/materials/MeshPhysicalMaterial.java index 0759a7cf..6d1a655a 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/materials/MeshPhysicalMaterial.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/materials/MeshPhysicalMaterial.java @@ -17,12 +17,12 @@ public class MeshPhysicalMaterial extends MeshStandardMaterial { /** * ClearCoat level, from 0.0 to 1.0. Default is 0.0. */ - public float clearCoat; + public float clearcoat; /** * How rough the clearCoat appears, from 0.0 to 1.0. Default is 0.0. */ - public float clearCoatRoughness; + public float clearcoatRoughness; /** * Used to check whether this or derived classes are mesh physical materials. Default is true. diff --git a/core/src/main/java/org/treblereel/gwt/three4g/materials/parameters/MeshPhysicalMaterialParameters.java b/core/src/main/java/org/treblereel/gwt/three4g/materials/parameters/MeshPhysicalMaterialParameters.java index 403afe63..95f2d81a 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/materials/parameters/MeshPhysicalMaterialParameters.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/materials/parameters/MeshPhysicalMaterialParameters.java @@ -13,12 +13,12 @@ public class MeshPhysicalMaterialParameters extends MeshStandardMaterialParamete /** * ClearCoat level, from 0.0 to 1.0. Default is 0.0. */ - public float clearCoat; + public float clearcoat; /** * How rough the clearCoat appears, from 0.0 to 1.0. Default is 0.0. */ - public float clearCoatRoughness; + public float clearcoatRoughness; /** * An object of the form: diff --git a/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.js b/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.js index 79f72980..00aeed27 100644 --- a/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.js +++ b/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.js @@ -61,31 +61,27 @@ // Missing in IE // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - ( function () { + Object.assign = function ( target ) { - Object.assign = function ( target ) { + if ( target === undefined || target === null ) { - if ( target === undefined || target === null ) { + throw new TypeError( 'Cannot convert undefined or null to object' ); - throw new TypeError( 'Cannot convert undefined or null to object' ); - - } - - var output = Object( target ); + } - for ( var index = 1; index < arguments.length; index ++ ) { + var output = Object( target ); - var source = arguments[ index ]; + for ( var index = 1; index < arguments.length; index ++ ) { - if ( source !== undefined && source !== null ) { + var source = arguments[ index ]; - for ( var nextKey in source ) { + if ( source !== undefined && source !== null ) { - if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) { + for ( var nextKey in source ) { - output[ nextKey ] = source[ nextKey ]; + if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) { - } + output[ nextKey ] = source[ nextKey ]; } @@ -93,11 +89,11 @@ } - return output; + } - }; + return output; - } )(); + }; } @@ -185,7 +181,7 @@ } ); - var REVISION = '107'; + var REVISION = '108'; var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; var CullFaceNone = 0; @@ -197,6 +193,7 @@ var BasicShadowMap = 0; var PCFShadowMap = 1; var PCFSoftShadowMap = 2; + var VSMShadowMap = 3; var FrontSide = 0; var BackSide = 1; var DoubleSide = 2; @@ -358,40 +355,36 @@ * @author mrdoob / http://mrdoob.com/ */ - var _Math = { - - DEG2RAD: Math.PI / 180, - RAD2DEG: 180 / Math.PI, + var _lut = []; - generateUUID: ( function () { + for ( var i = 0; i < 256; i ++ ) { - // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 - - var lut = []; + _lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); - for ( var i = 0; i < 256; i ++ ) { + } - lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); + var _Math = { - } + DEG2RAD: Math.PI / 180, + RAD2DEG: 180 / Math.PI, - return function generateUUID() { + generateUUID: function () { - var d0 = Math.random() * 0xffffffff | 0; - var d1 = Math.random() * 0xffffffff | 0; - var d2 = Math.random() * 0xffffffff | 0; - var d3 = Math.random() * 0xffffffff | 0; - var uuid = lut[ d0 & 0xff ] + lut[ d0 >> 8 & 0xff ] + lut[ d0 >> 16 & 0xff ] + lut[ d0 >> 24 & 0xff ] + '-' + - lut[ d1 & 0xff ] + lut[ d1 >> 8 & 0xff ] + '-' + lut[ d1 >> 16 & 0x0f | 0x40 ] + lut[ d1 >> 24 & 0xff ] + '-' + - lut[ d2 & 0x3f | 0x80 ] + lut[ d2 >> 8 & 0xff ] + '-' + lut[ d2 >> 16 & 0xff ] + lut[ d2 >> 24 & 0xff ] + - lut[ d3 & 0xff ] + lut[ d3 >> 8 & 0xff ] + lut[ d3 >> 16 & 0xff ] + lut[ d3 >> 24 & 0xff ]; + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 - // .toUpperCase() here flattens concatenated strings to save heap memory space. - return uuid.toUpperCase(); + var d0 = Math.random() * 0xffffffff | 0; + var d1 = Math.random() * 0xffffffff | 0; + var d2 = Math.random() * 0xffffffff | 0; + var d3 = Math.random() * 0xffffffff | 0; + var uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' + + _lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' + + _lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] + + _lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ]; - }; + // .toUpperCase() here flattens concatenated strings to save heap memory space. + return uuid.toUpperCase(); - } )(), + }, clamp: function ( value, min, max ) { @@ -1635,6 +1628,9 @@ * @author WestLangley / http://github.com/WestLangley */ + var _vector = new Vector3(); + var _quaternion = new Quaternion(); + function Vector3( x, y, z ) { this.x = x || 0; @@ -1856,35 +1852,23 @@ }, - applyEuler: function () { - - var quaternion = new Quaternion(); + applyEuler: function ( euler ) { - return function applyEuler( euler ) { - - if ( ! ( euler && euler.isEuler ) ) { - - console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - - } - - return this.applyQuaternion( quaternion.setFromEuler( euler ) ); - - }; + if ( ! ( euler && euler.isEuler ) ) { - }(), + console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - applyAxisAngle: function () { + } - var quaternion = new Quaternion(); + return this.applyQuaternion( _quaternion.setFromEuler( euler ) ); - return function applyAxisAngle( axis, angle ) { + }, - return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) ); + applyAxisAngle: function ( axis, angle ) { - }; + return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) ); - }(), + }, applyMatrix3: function ( m ) { @@ -2168,34 +2152,22 @@ }, - projectOnPlane: function () { - - var v1 = new Vector3(); + projectOnPlane: function ( planeNormal ) { - return function projectOnPlane( planeNormal ) { + _vector.copy( this ).projectOnVector( planeNormal ); - v1.copy( this ).projectOnVector( planeNormal ); + return this.sub( _vector ); - return this.sub( v1 ); - - }; - - }(), + }, - reflect: function () { + reflect: function ( normal ) { // reflect incident vector off plane orthogonal to normal // normal is assumed to have unit length - var v1 = new Vector3(); + return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); - return function reflect( normal ) { - - return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); - - }; - - }(), + }, angleTo: function ( v ) { @@ -2349,7 +2321,7 @@ * @author tschw */ - var _vector; + var _vector$1 = new Vector3(); function Matrix3() { @@ -2436,17 +2408,15 @@ applyToBufferAttribute: function ( attribute ) { - if ( _vector === undefined ) _vector = new Vector3(); - for ( var i = 0, l = attribute.count; i < l; i ++ ) { - _vector.x = attribute.getX( i ); - _vector.y = attribute.getY( i ); - _vector.z = attribute.getZ( i ); + _vector$1.x = attribute.getX( i ); + _vector$1.y = attribute.getY( i ); + _vector$1.z = attribute.getZ( i ); - _vector.applyMatrix3( this ); + _vector$1.applyMatrix3( this ); - attribute.setXYZ( i, _vector.x, _vector.y, _vector.z ); + attribute.setXYZ( i, _vector$1.x, _vector$1.y, _vector$1.z ); } @@ -3873,6 +3843,14 @@ } ); + var _v1 = new Vector3(); + var _m1 = new Matrix4(); + var _zero = new Vector3( 0, 0, 0 ); + var _one = new Vector3( 1, 1, 1 ); + var _x = new Vector3(); + var _y = new Vector3(); + var _z = new Vector3(); + /** * @author mrdoob / http://mrdoob.com/ * @author supereggbert / http://www.paulbrunt.co.uk/ @@ -3992,46 +3970,40 @@ }, - extractRotation: function () { - - var v1 = new Vector3(); + extractRotation: function ( m ) { - return function extractRotation( m ) { + // this method does not support reflection matrices - // this method does not support reflection matrices - - var te = this.elements; - var me = m.elements; - - var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length(); - var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length(); - var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length(); + var te = this.elements; + var me = m.elements; - te[ 0 ] = me[ 0 ] * scaleX; - te[ 1 ] = me[ 1 ] * scaleX; - te[ 2 ] = me[ 2 ] * scaleX; - te[ 3 ] = 0; + var scaleX = 1 / _v1.setFromMatrixColumn( m, 0 ).length(); + var scaleY = 1 / _v1.setFromMatrixColumn( m, 1 ).length(); + var scaleZ = 1 / _v1.setFromMatrixColumn( m, 2 ).length(); - te[ 4 ] = me[ 4 ] * scaleY; - te[ 5 ] = me[ 5 ] * scaleY; - te[ 6 ] = me[ 6 ] * scaleY; - te[ 7 ] = 0; + te[ 0 ] = me[ 0 ] * scaleX; + te[ 1 ] = me[ 1 ] * scaleX; + te[ 2 ] = me[ 2 ] * scaleX; + te[ 3 ] = 0; - te[ 8 ] = me[ 8 ] * scaleZ; - te[ 9 ] = me[ 9 ] * scaleZ; - te[ 10 ] = me[ 10 ] * scaleZ; - te[ 11 ] = 0; + te[ 4 ] = me[ 4 ] * scaleY; + te[ 5 ] = me[ 5 ] * scaleY; + te[ 6 ] = me[ 6 ] * scaleY; + te[ 7 ] = 0; - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + te[ 8 ] = me[ 8 ] * scaleZ; + te[ 9 ] = me[ 9 ] * scaleZ; + te[ 10 ] = me[ 10 ] * scaleZ; + te[ 11 ] = 0; - return this; + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; - }; + return this; - }(), + }, makeRotationFromEuler: function ( euler ) { @@ -4161,73 +4133,58 @@ }, - makeRotationFromQuaternion: function () { - - var zero = new Vector3( 0, 0, 0 ); - var one = new Vector3( 1, 1, 1 ); + makeRotationFromQuaternion: function ( q ) { - return function makeRotationFromQuaternion( q ) { + return this.compose( _zero, q, _one ); - return this.compose( zero, q, one ); - - }; - - }(), - - lookAt: function () { - - var x = new Vector3(); - var y = new Vector3(); - var z = new Vector3(); - - return function lookAt( eye, target, up ) { + }, - var te = this.elements; + lookAt: function ( eye, target, up ) { - z.subVectors( eye, target ); + var te = this.elements; - if ( z.lengthSq() === 0 ) { + _z.subVectors( eye, target ); - // eye and target are in the same position + if ( _z.lengthSq() === 0 ) { - z.z = 1; + // eye and target are in the same position - } + _z.z = 1; - z.normalize(); - x.crossVectors( up, z ); - - if ( x.lengthSq() === 0 ) { + } - // up and z are parallel + _z.normalize(); + _x.crossVectors( up, _z ); - if ( Math.abs( up.z ) === 1 ) { + if ( _x.lengthSq() === 0 ) { - z.x += 0.0001; + // up and z are parallel - } else { + if ( Math.abs( up.z ) === 1 ) { - z.z += 0.0001; + _z.x += 0.0001; - } + } else { - z.normalize(); - x.crossVectors( up, z ); + _z.z += 0.0001; } - x.normalize(); - y.crossVectors( z, x ); + _z.normalize(); + _x.crossVectors( up, _z ); - te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; - te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; - te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; + } - return this; + _x.normalize(); + _y.crossVectors( _z, _x ); - }; + te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; + te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; + te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; - }(), + return this; + + }, multiply: function ( m, n ) { @@ -4301,29 +4258,23 @@ }, - applyToBufferAttribute: function () { - - var v1 = new Vector3(); - - return function applyToBufferAttribute( attribute ) { - - for ( var i = 0, l = attribute.count; i < l; i ++ ) { + applyToBufferAttribute: function ( attribute ) { - v1.x = attribute.getX( i ); - v1.y = attribute.getY( i ); - v1.z = attribute.getZ( i ); + for ( var i = 0, l = attribute.count; i < l; i ++ ) { - v1.applyMatrix4( this ); + _v1.x = attribute.getX( i ); + _v1.y = attribute.getY( i ); + _v1.z = attribute.getZ( i ); - attribute.setXYZ( i, v1.x, v1.y, v1.z ); + _v1.applyMatrix4( this ); - } + attribute.setXYZ( i, _v1.x, _v1.y, _v1.z ); - return attribute; + } - }; + return attribute; - }(), + }, determinant: function () { @@ -4657,57 +4608,50 @@ }, - decompose: function () { - - var vector = new Vector3(); - var matrix = new Matrix4(); + decompose: function ( position, quaternion, scale ) { - return function decompose( position, quaternion, scale ) { - - var te = this.elements; - - var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); - var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); - var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); + var te = this.elements; - // if determine is negative, we need to invert one scale - var det = this.determinant(); - if ( det < 0 ) sx = - sx; + var sx = _v1.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); + var sy = _v1.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); + var sz = _v1.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); - position.x = te[ 12 ]; - position.y = te[ 13 ]; - position.z = te[ 14 ]; + // if determine is negative, we need to invert one scale + var det = this.determinant(); + if ( det < 0 ) sx = - sx; - // scale the rotation part - matrix.copy( this ); + position.x = te[ 12 ]; + position.y = te[ 13 ]; + position.z = te[ 14 ]; - var invSX = 1 / sx; - var invSY = 1 / sy; - var invSZ = 1 / sz; + // scale the rotation part + _m1.copy( this ); - matrix.elements[ 0 ] *= invSX; - matrix.elements[ 1 ] *= invSX; - matrix.elements[ 2 ] *= invSX; + var invSX = 1 / sx; + var invSY = 1 / sy; + var invSZ = 1 / sz; - matrix.elements[ 4 ] *= invSY; - matrix.elements[ 5 ] *= invSY; - matrix.elements[ 6 ] *= invSY; + _m1.elements[ 0 ] *= invSX; + _m1.elements[ 1 ] *= invSX; + _m1.elements[ 2 ] *= invSX; - matrix.elements[ 8 ] *= invSZ; - matrix.elements[ 9 ] *= invSZ; - matrix.elements[ 10 ] *= invSZ; + _m1.elements[ 4 ] *= invSY; + _m1.elements[ 5 ] *= invSY; + _m1.elements[ 6 ] *= invSY; - quaternion.setFromRotationMatrix( matrix ); + _m1.elements[ 8 ] *= invSZ; + _m1.elements[ 9 ] *= invSZ; + _m1.elements[ 10 ] *= invSZ; - scale.x = sx; - scale.y = sy; - scale.z = sz; + quaternion.setFromRotationMatrix( _m1 ); - return this; + scale.x = sx; + scale.y = sy; + scale.z = sz; - }; + return this; - }(), + }, makePerspective: function ( left, right, top, bottom, near, far ) { @@ -4823,7 +4767,8 @@ * @author bhouston / http://clara.io */ - var _matrix, _quaternion; + var _matrix = new Matrix4(); + var _quaternion$1 = new Quaternion(); function Euler( x, y, z, order ) { @@ -4963,7 +4908,7 @@ this._y = Math.asin( clamp( m13, - 1, 1 ) ); - if ( Math.abs( m13 ) < 0.99999 ) { + if ( Math.abs( m13 ) < 0.9999999 ) { this._x = Math.atan2( - m23, m33 ); this._z = Math.atan2( - m12, m11 ); @@ -4979,7 +4924,7 @@ this._x = Math.asin( - clamp( m23, - 1, 1 ) ); - if ( Math.abs( m23 ) < 0.99999 ) { + if ( Math.abs( m23 ) < 0.9999999 ) { this._y = Math.atan2( m13, m33 ); this._z = Math.atan2( m21, m22 ); @@ -4995,7 +4940,7 @@ this._x = Math.asin( clamp( m32, - 1, 1 ) ); - if ( Math.abs( m32 ) < 0.99999 ) { + if ( Math.abs( m32 ) < 0.9999999 ) { this._y = Math.atan2( - m31, m33 ); this._z = Math.atan2( - m12, m22 ); @@ -5011,7 +4956,7 @@ this._y = Math.asin( - clamp( m31, - 1, 1 ) ); - if ( Math.abs( m31 ) < 0.99999 ) { + if ( Math.abs( m31 ) < 0.9999999 ) { this._x = Math.atan2( m32, m33 ); this._z = Math.atan2( m21, m11 ); @@ -5027,7 +4972,7 @@ this._z = Math.asin( clamp( m21, - 1, 1 ) ); - if ( Math.abs( m21 ) < 0.99999 ) { + if ( Math.abs( m21 ) < 0.9999999 ) { this._x = Math.atan2( - m23, m22 ); this._y = Math.atan2( - m31, m11 ); @@ -5043,7 +4988,7 @@ this._z = Math.asin( - clamp( m12, - 1, 1 ) ); - if ( Math.abs( m12 ) < 0.99999 ) { + if ( Math.abs( m12 ) < 0.9999999 ) { this._x = Math.atan2( m32, m22 ); this._y = Math.atan2( m13, m11 ); @@ -5071,8 +5016,6 @@ setFromQuaternion: function ( q, order, update ) { - if ( _matrix === undefined ) _matrix = new Matrix4(); - _matrix.makeRotationFromQuaternion( q ); return this.setFromRotationMatrix( _matrix, order, update ); @@ -5089,11 +5032,9 @@ // WARNING: this discards revolution information -bhouston - if ( _quaternion === undefined ) _quaternion = new Quaternion(); + _quaternion$1.setFromEuler( this ); - _quaternion.setFromEuler( this ); - - return this.setFromQuaternion( _quaternion, newOrder ); + return this.setFromQuaternion( _quaternion$1, newOrder ); }, @@ -5180,6 +5121,12 @@ }, + enableAll: function () { + + this.mask = 0xffffffff | 0; + + }, + toggle: function ( channel ) { this.mask ^= 1 << channel | 0; @@ -5192,6 +5139,12 @@ }, + disableAll: function () { + + this.mask = 0; + + }, + test: function ( layers ) { return ( this.mask & layers.mask ) !== 0; @@ -5200,6 +5153,24 @@ } ); + var _object3DId = 0; + + var _v1$1 = new Vector3(); + var _q1 = new Quaternion(); + var _m1$1 = new Matrix4(); + var _target = new Vector3(); + + var _position = new Vector3(); + var _scale = new Vector3(); + var _quaternion$2 = new Quaternion(); + + var _xAxis = new Vector3( 1, 0, 0 ); + var _yAxis = new Vector3( 0, 1, 0 ); + var _zAxis = new Vector3( 0, 0, 1 ); + + var _addedEvent = { type: 'added' }; + var _removedEvent = { type: 'removed' }; + /** * @author mrdoob / http://mrdoob.com/ * @author mikael emtinger / http://gomo.se/ @@ -5208,11 +5179,9 @@ * @author elephantatwork / www.elephantatwork.ch */ - var object3DId = 0; - function Object3D() { - Object.defineProperty( this, 'id', { value: object3DId ++ } ); + Object.defineProperty( this, 'id', { value: _object3DId ++ } ); this.uuid = _Math.generateUUID(); @@ -5352,135 +5321,81 @@ }, - rotateOnAxis: function () { + rotateOnAxis: function ( axis, angle ) { // rotate object on axis in object space // axis is assumed to be normalized - var q1 = new Quaternion(); - - return function rotateOnAxis( axis, angle ) { + _q1.setFromAxisAngle( axis, angle ); - q1.setFromAxisAngle( axis, angle ); + this.quaternion.multiply( _q1 ); - this.quaternion.multiply( q1 ); - - return this; - - }; + return this; - }(), + }, - rotateOnWorldAxis: function () { + rotateOnWorldAxis: function ( axis, angle ) { // rotate object on axis in world space // axis is assumed to be normalized // method assumes no rotated parent - var q1 = new Quaternion(); - - return function rotateOnWorldAxis( axis, angle ) { - - q1.setFromAxisAngle( axis, angle ); + _q1.setFromAxisAngle( axis, angle ); - this.quaternion.premultiply( q1 ); + this.quaternion.premultiply( _q1 ); - return this; - - }; - - }(), - - rotateX: function () { - - var v1 = new Vector3( 1, 0, 0 ); - - return function rotateX( angle ) { - - return this.rotateOnAxis( v1, angle ); - - }; - - }(), - - rotateY: function () { + return this; - var v1 = new Vector3( 0, 1, 0 ); + }, - return function rotateY( angle ) { + rotateX: function ( angle ) { - return this.rotateOnAxis( v1, angle ); + return this.rotateOnAxis( _xAxis, angle ); - }; - - }(), + }, - rotateZ: function () { + rotateY: function ( angle ) { - var v1 = new Vector3( 0, 0, 1 ); + return this.rotateOnAxis( _yAxis, angle ); - return function rotateZ( angle ) { + }, - return this.rotateOnAxis( v1, angle ); + rotateZ: function ( angle ) { - }; + return this.rotateOnAxis( _zAxis, angle ); - }(), + }, - translateOnAxis: function () { + translateOnAxis: function ( axis, distance ) { // translate object by distance along axis in object space // axis is assumed to be normalized - var v1 = new Vector3(); - - return function translateOnAxis( axis, distance ) { - - v1.copy( axis ).applyQuaternion( this.quaternion ); - - this.position.add( v1.multiplyScalar( distance ) ); - - return this; - - }; - - }(), - - translateX: function () { - - var v1 = new Vector3( 1, 0, 0 ); + _v1$1.copy( axis ).applyQuaternion( this.quaternion ); - return function translateX( distance ) { + this.position.add( _v1$1.multiplyScalar( distance ) ); - return this.translateOnAxis( v1, distance ); - - }; - - }(), - - translateY: function () { - - var v1 = new Vector3( 0, 1, 0 ); + return this; - return function translateY( distance ) { + }, - return this.translateOnAxis( v1, distance ); + translateX: function ( distance ) { - }; + return this.translateOnAxis( _xAxis, distance ); - }(), + }, - translateZ: function () { + translateY: function ( distance ) { - var v1 = new Vector3( 0, 0, 1 ); + return this.translateOnAxis( _yAxis, distance ); - return function translateZ( distance ) { + }, - return this.translateOnAxis( v1, distance ); + translateZ: function ( distance ) { - }; + return this.translateOnAxis( _zAxis, distance ); - }(), + }, localToWorld: function ( vector ) { @@ -5488,68 +5403,53 @@ }, - worldToLocal: function () { - - var m1 = new Matrix4(); + worldToLocal: function ( vector ) { - return function worldToLocal( vector ) { + return vector.applyMatrix4( _m1$1.getInverse( this.matrixWorld ) ); - return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) ); - - }; - - }(), + }, - lookAt: function () { + lookAt: function ( x, y, z ) { // This method does not support objects having non-uniformly-scaled parent(s) - var q1 = new Quaternion(); - var m1 = new Matrix4(); - var target = new Vector3(); - var position = new Vector3(); - - return function lookAt( x, y, z ) { - - if ( x.isVector3 ) { - - target.copy( x ); + if ( x.isVector3 ) { - } else { + _target.copy( x ); - target.set( x, y, z ); + } else { - } + _target.set( x, y, z ); - var parent = this.parent; + } - this.updateWorldMatrix( true, false ); + var parent = this.parent; - position.setFromMatrixPosition( this.matrixWorld ); + this.updateWorldMatrix( true, false ); - if ( this.isCamera || this.isLight ) { + _position.setFromMatrixPosition( this.matrixWorld ); - m1.lookAt( position, target, this.up ); + if ( this.isCamera || this.isLight ) { - } else { + _m1$1.lookAt( _position, _target, this.up ); - m1.lookAt( target, position, this.up ); + } else { - } + _m1$1.lookAt( _target, _position, this.up ); - this.quaternion.setFromRotationMatrix( m1 ); + } - if ( parent ) { + this.quaternion.setFromRotationMatrix( _m1$1 ); - m1.extractRotation( parent.matrixWorld ); - q1.setFromRotationMatrix( m1 ); - this.quaternion.premultiply( q1.inverse() ); + if ( parent ) { - } + _m1$1.extractRotation( parent.matrixWorld ); + _q1.setFromRotationMatrix( _m1$1 ); + this.quaternion.premultiply( _q1.inverse() ); - }; + } - }(), + }, add: function ( object ) { @@ -5583,7 +5483,7 @@ object.parent = this; this.children.push( object ); - object.dispatchEvent( { type: 'added' } ); + object.dispatchEvent( _addedEvent ); } else { @@ -5616,7 +5516,7 @@ object.parent = null; this.children.splice( index, 1 ); - object.dispatchEvent( { type: 'removed' } ); + object.dispatchEvent( _removedEvent ); } @@ -5624,37 +5524,31 @@ }, - attach: function () { + attach: function ( object ) { // adds object as a child of this, while maintaining the object's world transform - var m = new Matrix4(); - - return function attach( object ) { + this.updateWorldMatrix( true, false ); - this.updateWorldMatrix( true, false ); + _m1$1.getInverse( this.matrixWorld ); - m.getInverse( this.matrixWorld ); + if ( object.parent !== null ) { - if ( object.parent !== null ) { + object.parent.updateWorldMatrix( true, false ); - object.parent.updateWorldMatrix( true, false ); + _m1$1.multiply( object.parent.matrixWorld ); - m.multiply( object.parent.matrixWorld ); - - } - - object.applyMatrix( m ); + } - object.updateWorldMatrix( false, false ); + object.applyMatrix( _m1$1 ); - this.add( object ); + object.updateWorldMatrix( false, false ); - return this; + this.add( object ); - }; + return this; - }(), + }, getObjectById: function ( id ) { @@ -5704,53 +5598,39 @@ }, - getWorldQuaternion: function () { - - var position = new Vector3(); - var scale = new Vector3(); + getWorldQuaternion: function ( target ) { - return function getWorldQuaternion( target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); - target = new Quaternion(); - - } - - this.updateMatrixWorld( true ); - - this.matrixWorld.decompose( position, target, scale ); + if ( target === undefined ) { - return target; + console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); + target = new Quaternion(); - }; + } - }(), + this.updateMatrixWorld( true ); - getWorldScale: function () { + this.matrixWorld.decompose( _position, target, _scale ); - var position = new Vector3(); - var quaternion = new Quaternion(); + return target; - return function getWorldScale( target ) { + }, - if ( target === undefined ) { + getWorldScale: function ( target ) { - console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); - target = new Vector3(); + if ( target === undefined ) { - } + console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); + target = new Vector3(); - this.updateMatrixWorld( true ); + } - this.matrixWorld.decompose( position, quaternion, target ); + this.updateMatrixWorld( true ); - return target; + this.matrixWorld.decompose( _position, _quaternion$2, target ); - }; + return target; - }(), + }, getWorldDirection: function ( target ) { @@ -6183,6 +6063,35 @@ } ); + var _points = [ + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3() + ]; + var _vector$2 = new Vector3(); + + // triangle centered vertices + + var _v0 = new Vector3(); + var _v1$2 = new Vector3(); + var _v2 = new Vector3(); + + // triangle edge vectors + + var _f0 = new Vector3(); + var _f1 = new Vector3(); + var _f2 = new Vector3(); + + var _center = new Vector3(); + var _extents = new Vector3(); + var _triangleNormal = new Vector3(); + var _testAxis = new Vector3(); + /** * @author bhouston / http://clara.io * @author WestLangley / http://github.com/WestLangley @@ -6288,22 +6197,16 @@ }, - setFromCenterAndSize: function () { + setFromCenterAndSize: function ( center, size ) { - var v1 = new Vector3(); + var halfSize = _vector$2.copy( size ).multiplyScalar( 0.5 ); - return function setFromCenterAndSize( center, size ) { + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); - - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); - - return this; - - }; + return this; - }(), + }, setFromObject: function ( object ) { @@ -6398,47 +6301,43 @@ }, - expandByObject: function () { + expandByObject: function ( object ) { + + var i, l; // Computes the world-axis-aligned bounding box of an object (including its children), // accounting for both the object's, and children's, world transforms - var scope, i, l; + object.updateWorldMatrix( false, false ); - var v1 = new Vector3(); - - function traverse( node ) { - - var geometry = node.geometry; - - if ( geometry !== undefined ) { + var geometry = object.geometry; - if ( geometry.isGeometry ) { + if ( geometry !== undefined ) { - var vertices = geometry.vertices; + if ( geometry.isGeometry ) { - for ( i = 0, l = vertices.length; i < l; i ++ ) { + var vertices = geometry.vertices; - v1.copy( vertices[ i ] ); - v1.applyMatrix4( node.matrixWorld ); + for ( i = 0, l = vertices.length; i < l; i ++ ) { - scope.expandByPoint( v1 ); + _vector$2.copy( vertices[ i ] ); + _vector$2.applyMatrix4( object.matrixWorld ); - } + this.expandByPoint( _vector$2 ); - } else if ( geometry.isBufferGeometry ) { + } - var attribute = geometry.attributes.position; + } else if ( geometry.isBufferGeometry ) { - if ( attribute !== undefined ) { + var attribute = geometry.attributes.position; - for ( i = 0, l = attribute.count; i < l; i ++ ) { + if ( attribute !== undefined ) { - v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld ); + for ( i = 0, l = attribute.count; i < l; i ++ ) { - scope.expandByPoint( v1 ); + _vector$2.fromBufferAttribute( attribute, i ).applyMatrix4( object.matrixWorld ); - } + this.expandByPoint( _vector$2 ); } @@ -6448,19 +6347,19 @@ } - return function expandByObject( object ) { + // - scope = this; + var children = object.children; - object.updateMatrixWorld( true ); + for ( i = 0, l = children.length; i < l; i ++ ) { - object.traverse( traverse ); + this.expandByObject( children[ i ] ); - return this; + } - }; + return this; - }(), + }, containsPoint: function ( point ) { @@ -6507,21 +6406,15 @@ }, - intersectsSphere: ( function () { - - var closestPoint = new Vector3(); - - return function intersectsSphere( sphere ) { - - // Find the point on the AABB closest to the sphere center. - this.clampPoint( sphere.center, closestPoint ); + intersectsSphere: function ( sphere ) { - // If that point is inside the sphere, the AABB and sphere intersect. - return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); + // Find the point on the AABB closest to the sphere center. + this.clampPoint( sphere.center, _vector$2 ); - }; + // If that point is inside the sphere, the AABB and sphere intersect. + return _vector$2.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); - } )(), + }, intersectsPlane: function ( plane ) { @@ -6570,106 +6463,58 @@ }, - intersectsTriangle: ( function () { - - // triangle centered vertices - var v0 = new Vector3(); - var v1 = new Vector3(); - var v2 = new Vector3(); - - // triangle edge vectors - var f0 = new Vector3(); - var f1 = new Vector3(); - var f2 = new Vector3(); - - var testAxis = new Vector3(); - - var center = new Vector3(); - var extents = new Vector3(); + intersectsTriangle: function ( triangle ) { - var triangleNormal = new Vector3(); - - function satForAxes( axes ) { - - var i, j; - - for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { - - testAxis.fromArray( axes, i ); - // project the aabb onto the seperating axis - var r = extents.x * Math.abs( testAxis.x ) + extents.y * Math.abs( testAxis.y ) + extents.z * Math.abs( testAxis.z ); - // project all 3 vertices of the triangle onto the seperating axis - var p0 = v0.dot( testAxis ); - var p1 = v1.dot( testAxis ); - var p2 = v2.dot( testAxis ); - // actual test, basically see if either of the most extreme of the triangle points intersects r - if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { - - // points of the projected triangle are outside the projected half-length of the aabb - // the axis is seperating and we can exit - return false; - - } - - } + if ( this.isEmpty() ) { - return true; + return false; } - return function intersectsTriangle( triangle ) { - - if ( this.isEmpty() ) { - - return false; - - } - - // compute box center and extents - this.getCenter( center ); - extents.subVectors( this.max, center ); + // compute box center and extents + this.getCenter( _center ); + _extents.subVectors( this.max, _center ); - // translate triangle to aabb origin - v0.subVectors( triangle.a, center ); - v1.subVectors( triangle.b, center ); - v2.subVectors( triangle.c, center ); + // translate triangle to aabb origin + _v0.subVectors( triangle.a, _center ); + _v1$2.subVectors( triangle.b, _center ); + _v2.subVectors( triangle.c, _center ); - // compute edge vectors for triangle - f0.subVectors( v1, v0 ); - f1.subVectors( v2, v1 ); - f2.subVectors( v0, v2 ); + // compute edge vectors for triangle + _f0.subVectors( _v1$2, _v0 ); + _f1.subVectors( _v2, _v1$2 ); + _f2.subVectors( _v0, _v2 ); - // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb - // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation - // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) - var axes = [ - 0, - f0.z, f0.y, 0, - f1.z, f1.y, 0, - f2.z, f2.y, - f0.z, 0, - f0.x, f1.z, 0, - f1.x, f2.z, 0, - f2.x, - - f0.y, f0.x, 0, - f1.y, f1.x, 0, - f2.y, f2.x, 0 - ]; - if ( ! satForAxes( axes ) ) { + // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb + // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation + // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) + var axes = [ + 0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y, + _f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x, + - _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0 + ]; + if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) { - return false; + return false; - } + } - // test 3 face normals from the aabb - axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; - if ( ! satForAxes( axes ) ) { + // test 3 face normals from the aabb + axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; + if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) { - return false; + return false; - } + } - // finally testing the face normal of the triangle - // use already existing triangle edge vectors here - triangleNormal.crossVectors( f0, f1 ); - axes = [ triangleNormal.x, triangleNormal.y, triangleNormal.z ]; - return satForAxes( axes ); + // finally testing the face normal of the triangle + // use already existing triangle edge vectors here + _triangleNormal.crossVectors( _f0, _f1 ); + axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ]; - }; + return satForAxes( axes, _v0, _v1$2, _v2, _extents ); - } )(), + }, clampPoint: function ( point, target ) { @@ -6684,41 +6529,30 @@ }, - distanceToPoint: function () { - - var v1 = new Vector3(); - - return function distanceToPoint( point ) { - - var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); - return clampedPoint.sub( point ).length(); - - }; + distanceToPoint: function ( point ) { - }(), + var clampedPoint = _vector$2.copy( point ).clamp( this.min, this.max ); - getBoundingSphere: function () { + return clampedPoint.sub( point ).length(); - var v1 = new Vector3(); + }, - return function getBoundingSphere( target ) { + getBoundingSphere: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.error( 'THREE.Box3: .getBoundingSphere() target is now required' ); - //target = new Sphere(); // removed to avoid cyclic dependency + console.error( 'THREE.Box3: .getBoundingSphere() target is now required' ); + //target = new Sphere(); // removed to avoid cyclic dependency - } - - this.getCenter( target.center ); + } - target.radius = this.getSize( v1 ).length() * 0.5; + this.getCenter( target.center ); - return target; + target.radius = this.getSize( _vector$2 ).length() * 0.5; - }; + return target; - }(), + }, intersect: function ( box ) { @@ -6741,41 +6575,26 @@ }, - applyMatrix4: function () { - - var points = [ - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3() - ]; - - return function applyMatrix4( matrix ) { - - // transform of empty box is an empty box. - if ( this.isEmpty() ) return this; + applyMatrix4: function ( matrix ) { - // NOTE: I am using a binary pattern to specify all 2^3 combinations below - points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 - points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 - points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 - points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 - points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 - points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 - points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 - points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 + // transform of empty box is an empty box. + if ( this.isEmpty() ) return this; - this.setFromPoints( points ); + // NOTE: I am using a binary pattern to specify all 2^3 combinations below + _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 + _points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 + _points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 + _points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 + _points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 + _points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 + _points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 + _points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 - return this; + this.setFromPoints( _points ); - }; + return this; - }(), + }, translate: function ( offset ) { @@ -6794,13 +6613,41 @@ } ); + function satForAxes( axes, v0, v1, v2, extents ) { + + var i, j; + + for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { + + _testAxis.fromArray( axes, i ); + // project the aabb onto the seperating axis + var r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z ); + // project all 3 vertices of the triangle onto the seperating axis + var p0 = v0.dot( _testAxis ); + var p1 = v1.dot( _testAxis ); + var p2 = v2.dot( _testAxis ); + // actual test, basically see if either of the most extreme of the triangle points intersects r + if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { + + // points of the projected triangle are outside the projected half-length of the aabb + // the axis is seperating and we can exit + return false; + + } + + } + + return true; + + } + + var _box = new Box3(); + /** * @author bhouston / http://clara.io * @author mrdoob / http://mrdoob.com/ */ - var _box; - function Sphere( center, radius ) { this.center = ( center !== undefined ) ? center : new Vector3(); @@ -6821,8 +6668,6 @@ setFromPoints: function ( points, optionalCenter ) { - if ( _box === undefined ) _box = new Box3(); - var center = this.center; if ( optionalCenter !== undefined ) { @@ -6967,6 +6812,15 @@ } ); + var _vector$3 = new Vector3(); + var _segCenter = new Vector3(); + var _segDir = new Vector3(); + var _diff = new Vector3(); + + var _edge1 = new Vector3(); + var _edge2 = new Vector3(); + var _normal = new Vector3(); + /** * @author bhouston / http://clara.io */ @@ -7025,19 +6879,13 @@ }, - recast: function () { - - var v1 = new Vector3(); + recast: function ( t ) { - return function recast( t ) { + this.origin.copy( this.at( t, _vector$3 ) ); - this.origin.copy( this.at( t, v1 ) ); - - return this; - - }; + return this; - }(), + }, closestPointToPoint: function ( point, target ) { @@ -7068,94 +6916,72 @@ }, - distanceSqToPoint: function () { - - var v1 = new Vector3(); - - return function distanceSqToPoint( point ) { - - var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction ); - - // point behind the ray - - if ( directionDistance < 0 ) { + distanceSqToPoint: function ( point ) { - return this.origin.distanceToSquared( point ); + var directionDistance = _vector$3.subVectors( point, this.origin ).dot( this.direction ); - } - - v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - - return v1.distanceToSquared( point ); - - }; + // point behind the ray - }(), + if ( directionDistance < 0 ) { - distanceSqToSegment: function () { + return this.origin.distanceToSquared( point ); - var segCenter = new Vector3(); - var segDir = new Vector3(); - var diff = new Vector3(); + } - return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { + _vector$3.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h - // It returns the min distance between the ray and the segment - // defined by v0 and v1 - // It can also set two optional targets : - // - The closest point on the ray - // - The closest point on the segment + return _vector$3.distanceToSquared( point ); - segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); - segDir.copy( v1 ).sub( v0 ).normalize(); - diff.copy( this.origin ).sub( segCenter ); + }, - var segExtent = v0.distanceTo( v1 ) * 0.5; - var a01 = - this.direction.dot( segDir ); - var b0 = diff.dot( this.direction ); - var b1 = - diff.dot( segDir ); - var c = diff.lengthSq(); - var det = Math.abs( 1 - a01 * a01 ); - var s0, s1, sqrDist, extDet; + distanceSqToSegment: function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { - if ( det > 0 ) { + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h + // It returns the min distance between the ray and the segment + // defined by v0 and v1 + // It can also set two optional targets : + // - The closest point on the ray + // - The closest point on the segment - // The ray and segment are not parallel. + _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); + _segDir.copy( v1 ).sub( v0 ).normalize(); + _diff.copy( this.origin ).sub( _segCenter ); - s0 = a01 * b1 - b0; - s1 = a01 * b0 - b1; - extDet = segExtent * det; + var segExtent = v0.distanceTo( v1 ) * 0.5; + var a01 = - this.direction.dot( _segDir ); + var b0 = _diff.dot( this.direction ); + var b1 = - _diff.dot( _segDir ); + var c = _diff.lengthSq(); + var det = Math.abs( 1 - a01 * a01 ); + var s0, s1, sqrDist, extDet; - if ( s0 >= 0 ) { + if ( det > 0 ) { - if ( s1 >= - extDet ) { + // The ray and segment are not parallel. - if ( s1 <= extDet ) { + s0 = a01 * b1 - b0; + s1 = a01 * b0 - b1; + extDet = segExtent * det; - // region 0 - // Minimum at interior points of ray and segment. + if ( s0 >= 0 ) { - var invDet = 1 / det; - s0 *= invDet; - s1 *= invDet; - sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; + if ( s1 >= - extDet ) { - } else { + if ( s1 <= extDet ) { - // region 1 + // region 0 + // Minimum at interior points of ray and segment. - s1 = segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - - } + var invDet = 1 / det; + s0 *= invDet; + s1 *= invDet; + sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; } else { - // region 5 + // region 1 - s1 = - segExtent; + s1 = segExtent; s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; @@ -7163,97 +6989,99 @@ } else { - if ( s1 <= - extDet ) { + // region 5 - // region 4 + s1 = - segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + } - } else if ( s1 <= extDet ) { + } else { - // region 3 + if ( s1 <= - extDet ) { - s0 = 0; - s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = s1 * ( s1 + 2 * b1 ) + c; + // region 4 - } else { + s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - // region 2 + } else if ( s1 <= extDet ) { - s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + // region 3 - } + s0 = 0; + s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = s1 * ( s1 + 2 * b1 ) + c; - } + } else { - } else { + // region 2 - // Ray and segment are parallel. + s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - s1 = ( a01 > 0 ) ? - segExtent : segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + } } - if ( optionalPointOnRay ) { + } else { - optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); + // Ray and segment are parallel. - } + s1 = ( a01 > 0 ) ? - segExtent : segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - if ( optionalPointOnSegment ) { + } - optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter ); + if ( optionalPointOnRay ) { - } + optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); - return sqrDist; + } - }; + if ( optionalPointOnSegment ) { - }(), + optionalPointOnSegment.copy( _segDir ).multiplyScalar( s1 ).add( _segCenter ); - intersectSphere: function () { + } - var v1 = new Vector3(); + return sqrDist; - return function intersectSphere( sphere, target ) { + }, - v1.subVectors( sphere.center, this.origin ); - var tca = v1.dot( this.direction ); - var d2 = v1.dot( v1 ) - tca * tca; - var radius2 = sphere.radius * sphere.radius; + intersectSphere: function ( sphere, target ) { - if ( d2 > radius2 ) return null; + _vector$3.subVectors( sphere.center, this.origin ); + var tca = _vector$3.dot( this.direction ); + var d2 = _vector$3.dot( _vector$3 ) - tca * tca; + var radius2 = sphere.radius * sphere.radius; - var thc = Math.sqrt( radius2 - d2 ); + if ( d2 > radius2 ) return null; - // t0 = first intersect point - entrance on front of sphere - var t0 = tca - thc; + var thc = Math.sqrt( radius2 - d2 ); - // t1 = second intersect point - exit point on back of sphere - var t1 = tca + thc; + // t0 = first intersect point - entrance on front of sphere + var t0 = tca - thc; - // test to see if both t0 and t1 are behind the ray - if so, return null - if ( t0 < 0 && t1 < 0 ) return null; + // t1 = second intersect point - exit point on back of sphere + var t1 = tca + thc; - // test to see if t0 is behind the ray: - // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, - // in order to always return an intersect point that is in front of the ray. - if ( t0 < 0 ) return this.at( t1, target ); + // test to see if both t0 and t1 are behind the ray - if so, return null + if ( t0 < 0 && t1 < 0 ) return null; - // else t0 is in front of the ray, so return the first collision point scaled by t0 - return this.at( t0, target ); + // test to see if t0 is behind the ray: + // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, + // in order to always return an intersect point that is in front of the ray. + if ( t0 < 0 ) return this.at( t1, target ); - }; + // else t0 is in front of the ray, so return the first collision point scaled by t0 + return this.at( t0, target ); - }(), + }, intersectsSphere: function ( sphere ) { @@ -7397,100 +7225,86 @@ }, - intersectsBox: ( function () { - - var v = new Vector3(); - - return function intersectsBox( box ) { - - return this.intersectBox( box, v ) !== null; + intersectsBox: function ( box ) { - }; + return this.intersectBox( box, _vector$3 ) !== null; - } )(), + }, - intersectTriangle: function () { + intersectTriangle: function ( a, b, c, backfaceCulling, target ) { // Compute the offset origin, edges, and normal. - var diff = new Vector3(); - var edge1 = new Vector3(); - var edge2 = new Vector3(); - var normal = new Vector3(); - return function intersectTriangle( a, b, c, backfaceCulling, target ) { + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h - // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h + _edge1.subVectors( b, a ); + _edge2.subVectors( c, a ); + _normal.crossVectors( _edge1, _edge2 ); - edge1.subVectors( b, a ); - edge2.subVectors( c, a ); - normal.crossVectors( edge1, edge2 ); + // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, + // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by + // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) + // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) + // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) + var DdN = this.direction.dot( _normal ); + var sign; - // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, - // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by - // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) - // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) - // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) - var DdN = this.direction.dot( normal ); - var sign; + if ( DdN > 0 ) { - if ( DdN > 0 ) { + if ( backfaceCulling ) return null; + sign = 1; - if ( backfaceCulling ) return null; - sign = 1; + } else if ( DdN < 0 ) { - } else if ( DdN < 0 ) { + sign = - 1; + DdN = - DdN; - sign = - 1; - DdN = - DdN; - - } else { - - return null; + } else { - } + return null; - diff.subVectors( this.origin, a ); - var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) ); + } - // b1 < 0, no intersection - if ( DdQxE2 < 0 ) { + _diff.subVectors( this.origin, a ); + var DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) ); - return null; + // b1 < 0, no intersection + if ( DdQxE2 < 0 ) { - } + return null; - var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) ); + } - // b2 < 0, no intersection - if ( DdE1xQ < 0 ) { + var DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); - return null; + // b2 < 0, no intersection + if ( DdE1xQ < 0 ) { - } + return null; - // b1+b2 > 1, no intersection - if ( DdQxE2 + DdE1xQ > DdN ) { + } - return null; + // b1+b2 > 1, no intersection + if ( DdQxE2 + DdE1xQ > DdN ) { - } + return null; - // Line intersects triangle, check if ray does. - var QdN = - sign * diff.dot( normal ); + } - // t < 0, no intersection - if ( QdN < 0 ) { + // Line intersects triangle, check if ray does. + var QdN = - sign * _diff.dot( _normal ); - return null; + // t < 0, no intersection + if ( QdN < 0 ) { - } + return null; - // Ray intersects triangle. - return this.at( QdN / DdN, target ); + } - }; + // Ray intersects triangle. + return this.at( QdN / DdN, target ); - }(), + }, applyMatrix4: function ( matrix4 ) { @@ -7514,6 +7328,18 @@ * @author mrdoob / http://mrdoob.com/ */ + var _v0$1 = new Vector3(); + var _v1$3 = new Vector3(); + var _v2$1 = new Vector3(); + var _v3 = new Vector3(); + + var _vab = new Vector3(); + var _vac = new Vector3(); + var _vbc = new Vector3(); + var _vap = new Vector3(); + var _vbp = new Vector3(); + var _vcp = new Vector3(); + function Triangle( a, b, c ) { this.a = ( a !== undefined ) ? a : new Vector3(); @@ -7524,134 +7350,101 @@ Object.assign( Triangle, { - getNormal: function () { + getNormal: function ( a, b, c, target ) { - var v0 = new Vector3(); - - return function getNormal( a, b, c, target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Triangle: .getNormal() target is now required' ); - target = new Vector3(); + if ( target === undefined ) { - } + console.warn( 'THREE.Triangle: .getNormal() target is now required' ); + target = new Vector3(); - target.subVectors( c, b ); - v0.subVectors( a, b ); - target.cross( v0 ); + } - var targetLengthSq = target.lengthSq(); - if ( targetLengthSq > 0 ) { + target.subVectors( c, b ); + _v0$1.subVectors( a, b ); + target.cross( _v0$1 ); - return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); + var targetLengthSq = target.lengthSq(); + if ( targetLengthSq > 0 ) { - } + return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); - return target.set( 0, 0, 0 ); + } - }; + return target.set( 0, 0, 0 ); - }(), + }, // static/instance method to calculate barycentric coordinates // based on: http://www.blackpawn.com/texts/pointinpoly/default.html - getBarycoord: function () { - - var v0 = new Vector3(); - var v1 = new Vector3(); - var v2 = new Vector3(); - - return function getBarycoord( point, a, b, c, target ) { - - v0.subVectors( c, a ); - v1.subVectors( b, a ); - v2.subVectors( point, a ); + getBarycoord: function ( point, a, b, c, target ) { - var dot00 = v0.dot( v0 ); - var dot01 = v0.dot( v1 ); - var dot02 = v0.dot( v2 ); - var dot11 = v1.dot( v1 ); - var dot12 = v1.dot( v2 ); - - var denom = ( dot00 * dot11 - dot01 * dot01 ); - - if ( target === undefined ) { - - console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); - target = new Vector3(); - - } + _v0$1.subVectors( c, a ); + _v1$3.subVectors( b, a ); + _v2$1.subVectors( point, a ); - // collinear or singular triangle - if ( denom === 0 ) { + var dot00 = _v0$1.dot( _v0$1 ); + var dot01 = _v0$1.dot( _v1$3 ); + var dot02 = _v0$1.dot( _v2$1 ); + var dot11 = _v1$3.dot( _v1$3 ); + var dot12 = _v1$3.dot( _v2$1 ); - // arbitrary location outside of triangle? - // not sure if this is the best idea, maybe should be returning undefined - return target.set( - 2, - 1, - 1 ); + var denom = ( dot00 * dot11 - dot01 * dot01 ); - } - - var invDenom = 1 / denom; - var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; - var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; - - // barycentric coordinates must always sum to 1 - return target.set( 1 - u - v, v, u ); - - }; - - }(), - - containsPoint: function () { + if ( target === undefined ) { - var v1 = new Vector3(); + console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); + target = new Vector3(); - return function containsPoint( point, a, b, c ) { + } - Triangle.getBarycoord( point, a, b, c, v1 ); + // collinear or singular triangle + if ( denom === 0 ) { - return ( v1.x >= 0 ) && ( v1.y >= 0 ) && ( ( v1.x + v1.y ) <= 1 ); + // arbitrary location outside of triangle? + // not sure if this is the best idea, maybe should be returning undefined + return target.set( - 2, - 1, - 1 ); - }; + } - }(), + var invDenom = 1 / denom; + var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; + var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; - getUV: function () { + // barycentric coordinates must always sum to 1 + return target.set( 1 - u - v, v, u ); - var barycoord = new Vector3(); + }, - return function getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) { + containsPoint: function ( point, a, b, c ) { - this.getBarycoord( point, p1, p2, p3, barycoord ); + Triangle.getBarycoord( point, a, b, c, _v3 ); - target.set( 0, 0 ); - target.addScaledVector( uv1, barycoord.x ); - target.addScaledVector( uv2, barycoord.y ); - target.addScaledVector( uv3, barycoord.z ); + return ( _v3.x >= 0 ) && ( _v3.y >= 0 ) && ( ( _v3.x + _v3.y ) <= 1 ); - return target; + }, - }; + getUV: function ( point, p1, p2, p3, uv1, uv2, uv3, target ) { - }(), + this.getBarycoord( point, p1, p2, p3, _v3 ); - isFrontFacing: function () { + target.set( 0, 0 ); + target.addScaledVector( uv1, _v3.x ); + target.addScaledVector( uv2, _v3.y ); + target.addScaledVector( uv3, _v3.z ); - var v0 = new Vector3(); - var v1 = new Vector3(); + return target; - return function isFrontFacing( a, b, c, direction ) { + }, - v0.subVectors( c, b ); - v1.subVectors( a, b ); + isFrontFacing: function ( a, b, c, direction ) { - // strictly front facing - return ( v0.cross( v1 ).dot( direction ) < 0 ) ? true : false; + _v0$1.subVectors( c, b ); + _v1$3.subVectors( a, b ); - }; + // strictly front facing + return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false; - }() + } } ); @@ -7695,19 +7488,12 @@ getArea: function () { - var v0 = new Vector3(); - var v1 = new Vector3(); + _v0$1.subVectors( this.c, this.b ); + _v1$3.subVectors( this.a, this.b ); - return function getArea() { + return _v0$1.cross( _v1$3 ).length() * 0.5; - v0.subVectors( this.c, this.b ); - v1.subVectors( this.a, this.b ); - - return v0.cross( v1 ).length() * 0.5; - - }; - - }(), + }, getMidpoint: function ( target ) { @@ -7771,103 +7557,93 @@ }, - closestPointToPoint: function () { + closestPointToPoint: function ( p, target ) { - var vab = new Vector3(); - var vac = new Vector3(); - var vbc = new Vector3(); - var vap = new Vector3(); - var vbp = new Vector3(); - var vcp = new Vector3(); - - return function closestPointToPoint( p, target ) { - - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); + target = new Vector3(); - } + } - var a = this.a, b = this.b, c = this.c; - var v, w; + var a = this.a, b = this.b, c = this.c; + var v, w; - // algorithm thanks to Real-Time Collision Detection by Christer Ericson, - // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., - // under the accompanying license; see chapter 5.1.5 for detailed explanation. - // basically, we're distinguishing which of the voronoi regions of the triangle - // the point lies in with the minimum amount of redundant computation. + // algorithm thanks to Real-Time Collision Detection by Christer Ericson, + // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., + // under the accompanying license; see chapter 5.1.5 for detailed explanation. + // basically, we're distinguishing which of the voronoi regions of the triangle + // the point lies in with the minimum amount of redundant computation. - vab.subVectors( b, a ); - vac.subVectors( c, a ); - vap.subVectors( p, a ); - var d1 = vab.dot( vap ); - var d2 = vac.dot( vap ); - if ( d1 <= 0 && d2 <= 0 ) { + _vab.subVectors( b, a ); + _vac.subVectors( c, a ); + _vap.subVectors( p, a ); + var d1 = _vab.dot( _vap ); + var d2 = _vac.dot( _vap ); + if ( d1 <= 0 && d2 <= 0 ) { - // vertex region of A; barycentric coords (1, 0, 0) - return target.copy( a ); + // vertex region of A; barycentric coords (1, 0, 0) + return target.copy( a ); - } + } - vbp.subVectors( p, b ); - var d3 = vab.dot( vbp ); - var d4 = vac.dot( vbp ); - if ( d3 >= 0 && d4 <= d3 ) { + _vbp.subVectors( p, b ); + var d3 = _vab.dot( _vbp ); + var d4 = _vac.dot( _vbp ); + if ( d3 >= 0 && d4 <= d3 ) { - // vertex region of B; barycentric coords (0, 1, 0) - return target.copy( b ); + // vertex region of B; barycentric coords (0, 1, 0) + return target.copy( b ); - } + } - var vc = d1 * d4 - d3 * d2; - if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { + var vc = d1 * d4 - d3 * d2; + if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { - v = d1 / ( d1 - d3 ); - // edge region of AB; barycentric coords (1-v, v, 0) - return target.copy( a ).addScaledVector( vab, v ); + v = d1 / ( d1 - d3 ); + // edge region of AB; barycentric coords (1-v, v, 0) + return target.copy( a ).addScaledVector( _vab, v ); - } + } - vcp.subVectors( p, c ); - var d5 = vab.dot( vcp ); - var d6 = vac.dot( vcp ); - if ( d6 >= 0 && d5 <= d6 ) { + _vcp.subVectors( p, c ); + var d5 = _vab.dot( _vcp ); + var d6 = _vac.dot( _vcp ); + if ( d6 >= 0 && d5 <= d6 ) { - // vertex region of C; barycentric coords (0, 0, 1) - return target.copy( c ); + // vertex region of C; barycentric coords (0, 0, 1) + return target.copy( c ); - } + } - var vb = d5 * d2 - d1 * d6; - if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { + var vb = d5 * d2 - d1 * d6; + if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { - w = d2 / ( d2 - d6 ); - // edge region of AC; barycentric coords (1-w, 0, w) - return target.copy( a ).addScaledVector( vac, w ); + w = d2 / ( d2 - d6 ); + // edge region of AC; barycentric coords (1-w, 0, w) + return target.copy( a ).addScaledVector( _vac, w ); - } + } - var va = d3 * d6 - d5 * d4; - if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { + var va = d3 * d6 - d5 * d4; + if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { - vbc.subVectors( c, b ); - w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); - // edge region of BC; barycentric coords (0, 1-w, w) - return target.copy( b ).addScaledVector( vbc, w ); // edge region of BC + _vbc.subVectors( c, b ); + w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); + // edge region of BC; barycentric coords (0, 1-w, w) + return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC - } + } - // face region - var denom = 1 / ( va + vb + vc ); - // u = va * denom - v = vb * denom; - w = vc * denom; - return target.copy( a ).addScaledVector( vab, v ).addScaledVector( vac, w ); + // face region + var denom = 1 / ( va + vb + vc ); + // u = va * denom + v = vb * denom; + w = vc * denom; - }; + return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w ); - }(), + }, equals: function ( triangle ) { @@ -7881,7 +7657,7 @@ * @author mrdoob / http://mrdoob.com/ */ - var ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, + var _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, @@ -7906,6 +7682,9 @@ 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; + var _hslA = { h: 0, s: 0, l: 0 }; + var _hslB = { h: 0, s: 0, l: 0 }; + function Color( r, g, b ) { if ( g === undefined && b === undefined ) { @@ -8136,7 +7915,7 @@ if ( style && style.length > 0 ) { // color keywords - var hex = ColorKeywords[ style ]; + var hex = _colorKeywords[ style ]; if ( hex !== undefined ) { @@ -8318,23 +8097,17 @@ }, - offsetHSL: function () { - - var hsl = {}; + offsetHSL: function ( h, s, l ) { - return function ( h, s, l ) { + this.getHSL( _hslA ); - this.getHSL( hsl ); + _hslA.h += h; _hslA.s += s; _hslA.l += l; - hsl.h += h; hsl.s += s; hsl.l += l; + this.setHSL( _hslA.h, _hslA.s, _hslA.l ); - this.setHSL( hsl.h, hsl.s, hsl.l ); - - return this; - - }; + return this; - }(), + }, add: function ( color ) { @@ -8406,27 +8179,20 @@ }, - lerpHSL: function () { - - var hslA = { h: 0, s: 0, l: 0 }; - var hslB = { h: 0, s: 0, l: 0 }; - - return function lerpHSL( color, alpha ) { + lerpHSL: function ( color, alpha ) { - this.getHSL( hslA ); - color.getHSL( hslB ); + this.getHSL( _hslA ); + color.getHSL( _hslB ); - var h = _Math.lerp( hslA.h, hslB.h, alpha ); - var s = _Math.lerp( hslA.s, hslB.s, alpha ); - var l = _Math.lerp( hslA.l, hslB.l, alpha ); + var h = _Math.lerp( _hslA.h, _hslB.h, alpha ); + var s = _Math.lerp( _hslA.s, _hslB.s, alpha ); + var l = _Math.lerp( _hslA.l, _hslB.l, alpha ); - this.setHSL( h, s, l ); - - return this; + this.setHSL( h, s, l ); - }; + return this; - }(), + }, equals: function ( c ) { @@ -8593,6 +8359,8 @@ this.visible = true; + this.toneMapped = true; + this.userData = {}; this.needsUpdate = true; @@ -8695,8 +8463,15 @@ if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); if ( this.shininess !== undefined ) data.shininess = this.shininess; - if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat; - if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness; + if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; + if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; + + if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { + + data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; + data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); + + } if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; @@ -8806,6 +8581,9 @@ if ( this.skinning === true ) data.skinning = true; if ( this.visible === false ) data.visible = false; + + if ( this.toneMapped === false ) data.toneMapped = false; + if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; // TODO: Copied from Object3D.toJSON @@ -8894,6 +8672,9 @@ this.premultipliedAlpha = source.premultipliedAlpha; this.visible = source.visible; + + this.toneMapped = source.toneMapped; + this.userData = JSON.parse( JSON.stringify( source.userData ) ); this.clipShadows = source.clipShadows; @@ -9771,11 +9552,18 @@ * @author mrdoob / http://mrdoob.com/ */ - var bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id + var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id + + var _m1$2 = new Matrix4(); + var _obj = new Object3D(); + var _offset = new Vector3(); + var _box$1 = new Box3(); + var _boxMorphTargets = new Box3(); + var _vector$4 = new Vector3(); function BufferGeometry() { - Object.defineProperty( this, 'id', { value: bufferGeometryId += 2 } ); + Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } ); this.uuid = _Math.generateUUID(); @@ -9938,129 +9726,89 @@ }, - rotateX: function () { + rotateX: function ( angle ) { // rotate geometry around world x-axis - var m1 = new Matrix4(); + _m1$2.makeRotationX( angle ); - return function rotateX( angle ) { + this.applyMatrix( _m1$2 ); - m1.makeRotationX( angle ); - - this.applyMatrix( m1 ); - - return this; - - }; + return this; - }(), + }, - rotateY: function () { + rotateY: function ( angle ) { // rotate geometry around world y-axis - var m1 = new Matrix4(); - - return function rotateY( angle ) { - - m1.makeRotationY( angle ); + _m1$2.makeRotationY( angle ); - this.applyMatrix( m1 ); + this.applyMatrix( _m1$2 ); - return this; - - }; + return this; - }(), + }, - rotateZ: function () { + rotateZ: function ( angle ) { // rotate geometry around world z-axis - var m1 = new Matrix4(); - - return function rotateZ( angle ) { - - m1.makeRotationZ( angle ); - - this.applyMatrix( m1 ); + _m1$2.makeRotationZ( angle ); - return this; + this.applyMatrix( _m1$2 ); - }; + return this; - }(), + }, - translate: function () { + translate: function ( x, y, z ) { // translate geometry - var m1 = new Matrix4(); + _m1$2.makeTranslation( x, y, z ); - return function translate( x, y, z ) { + this.applyMatrix( _m1$2 ); - m1.makeTranslation( x, y, z ); - - this.applyMatrix( m1 ); - - return this; - - }; + return this; - }(), + }, - scale: function () { + scale: function ( x, y, z ) { // scale geometry - var m1 = new Matrix4(); - - return function scale( x, y, z ) { - - m1.makeScale( x, y, z ); + _m1$2.makeScale( x, y, z ); - this.applyMatrix( m1 ); + this.applyMatrix( _m1$2 ); - return this; - - }; - - }(), - - lookAt: function () { + return this; - var obj = new Object3D(); + }, - return function lookAt( vector ) { + lookAt: function ( vector ) { - obj.lookAt( vector ); + _obj.lookAt( vector ); - obj.updateMatrix(); + _obj.updateMatrix(); - this.applyMatrix( obj.matrix ); + this.applyMatrix( _obj.matrix ); - }; + return this; - }(), + }, center: function () { - var offset = new Vector3(); - - return function center() { + this.computeBoundingBox(); - this.computeBoundingBox(); + this.boundingBox.getCenter( _offset ).negate(); - this.boundingBox.getCenter( offset ).negate(); + this.translate( _offset.x, _offset.y, _offset.z ); - this.translate( offset.x, offset.y, offset.z ); - - return this; - - }; + return this; - }(), + }, setFromObject: function ( object ) { @@ -10357,144 +10105,130 @@ computeBoundingBox: function () { - var box = new Box3(); - - return function computeBoundingBox() { - - if ( this.boundingBox === null ) { + if ( this.boundingBox === null ) { - this.boundingBox = new Box3(); + this.boundingBox = new Box3(); - } + } - var position = this.attributes.position; - var morphAttributesPosition = this.morphAttributes.position; + var position = this.attributes.position; + var morphAttributesPosition = this.morphAttributes.position; - if ( position !== undefined ) { + if ( position !== undefined ) { - this.boundingBox.setFromBufferAttribute( position ); + this.boundingBox.setFromBufferAttribute( position ); - // process morph attributes if present + // process morph attributes if present - if ( morphAttributesPosition ) { + if ( morphAttributesPosition ) { - for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - var morphAttribute = morphAttributesPosition[ i ]; - box.setFromBufferAttribute( morphAttribute ); + var morphAttribute = morphAttributesPosition[ i ]; + _box$1.setFromBufferAttribute( morphAttribute ); - this.boundingBox.expandByPoint( box.min ); - this.boundingBox.expandByPoint( box.max ); - - } + this.boundingBox.expandByPoint( _box$1.min ); + this.boundingBox.expandByPoint( _box$1.max ); } - } else { - - this.boundingBox.makeEmpty(); - } - if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - - console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); + } else { - } + this.boundingBox.makeEmpty(); - }; + } - }(), + if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - computeBoundingSphere: function () { + console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); - var box = new Box3(); - var boxMorphTargets = new Box3(); - var vector = new Vector3(); + } - return function computeBoundingSphere() { + }, - if ( this.boundingSphere === null ) { + computeBoundingSphere: function () { - this.boundingSphere = new Sphere(); + if ( this.boundingSphere === null ) { - } + this.boundingSphere = new Sphere(); - var position = this.attributes.position; - var morphAttributesPosition = this.morphAttributes.position; + } - if ( position ) { + var position = this.attributes.position; + var morphAttributesPosition = this.morphAttributes.position; - // first, find the center of the bounding sphere + if ( position ) { - var center = this.boundingSphere.center; + // first, find the center of the bounding sphere - box.setFromBufferAttribute( position ); + var center = this.boundingSphere.center; - // process morph attributes if present + _box$1.setFromBufferAttribute( position ); - if ( morphAttributesPosition ) { + // process morph attributes if present - for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + if ( morphAttributesPosition ) { - var morphAttribute = morphAttributesPosition[ i ]; - boxMorphTargets.setFromBufferAttribute( morphAttribute ); + for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - box.expandByPoint( boxMorphTargets.min ); - box.expandByPoint( boxMorphTargets.max ); + var morphAttribute = morphAttributesPosition[ i ]; + _boxMorphTargets.setFromBufferAttribute( morphAttribute ); - } + _box$1.expandByPoint( _boxMorphTargets.min ); + _box$1.expandByPoint( _boxMorphTargets.max ); } - box.getCenter( center ); + } - // second, try to find a boundingSphere with a radius smaller than the - // boundingSphere of the boundingBox: sqrt(3) smaller in the best case + _box$1.getCenter( center ); - var maxRadiusSq = 0; + // second, try to find a boundingSphere with a radius smaller than the + // boundingSphere of the boundingBox: sqrt(3) smaller in the best case - for ( var i = 0, il = position.count; i < il; i ++ ) { + var maxRadiusSq = 0; - vector.fromBufferAttribute( position, i ); + for ( var i = 0, il = position.count; i < il; i ++ ) { - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); + _vector$4.fromBufferAttribute( position, i ); - } + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) ); - // process morph attributes if present + } - if ( morphAttributesPosition ) { + // process morph attributes if present - for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + if ( morphAttributesPosition ) { - var morphAttribute = morphAttributesPosition[ i ]; + for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) { + var morphAttribute = morphAttributesPosition[ i ]; - vector.fromBufferAttribute( morphAttribute, j ); + for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) { - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); + _vector$4.fromBufferAttribute( morphAttribute, j ); - } + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) ); } } - this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); + } - if ( isNaN( this.boundingSphere.radius ) ) { + this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); - console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); + if ( isNaN( this.boundingSphere.radius ) ) { - } + console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); } - }; + } - }(), + }, computeFaceNormals: function () { @@ -10656,27 +10390,21 @@ normalizeNormals: function () { - var vector = new Vector3(); - - return function normalizeNormals() { + var normals = this.attributes.normal; - var normals = this.attributes.normal; + for ( var i = 0, il = normals.count; i < il; i ++ ) { - for ( var i = 0, il = normals.count; i < il; i ++ ) { + _vector$4.x = normals.getX( i ); + _vector$4.y = normals.getY( i ); + _vector$4.z = normals.getZ( i ); - vector.x = normals.getX( i ); - vector.y = normals.getY( i ); - vector.z = normals.getZ( i ); + _vector$4.normalize(); - vector.normalize(); + normals.setXYZ( i, _vector$4.x, _vector$4.y, _vector$4.z ); - normals.setXYZ( i, vector.x, vector.y, vector.z ); - - } - - }; + } - }(), + }, toNonIndexed: function () { @@ -11029,6 +10757,29 @@ * @author jonobr1 / http://jonobr1.com/ */ + var _inverseMatrix = new Matrix4(); + var _ray = new Ray(); + var _sphere = new Sphere(); + + var _vA = new Vector3(); + var _vB = new Vector3(); + var _vC = new Vector3(); + + var _tempA = new Vector3(); + var _tempB = new Vector3(); + var _tempC = new Vector3(); + + var _morphA = new Vector3(); + var _morphB = new Vector3(); + var _morphC = new Vector3(); + + var _uvA = new Vector2(); + var _uvB = new Vector2(); + var _uvC = new Vector2(); + + var _intersectionPoint = new Vector3(); + var _intersectionPointWorld = new Vector3(); + function Mesh( geometry, material ) { Object3D.call( this ); @@ -11124,357 +10875,330 @@ }, - raycast: ( function () { - - var inverseMatrix = new Matrix4(); - var ray = new Ray(); - var sphere = new Sphere(); - - var vA = new Vector3(); - var vB = new Vector3(); - var vC = new Vector3(); - - var tempA = new Vector3(); - var tempB = new Vector3(); - var tempC = new Vector3(); - - var morphA = new Vector3(); - var morphB = new Vector3(); - var morphC = new Vector3(); - - var uvA = new Vector2(); - var uvB = new Vector2(); - var uvC = new Vector2(); - - var intersectionPoint = new Vector3(); - var intersectionPointWorld = new Vector3(); - - function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { + raycast: function ( raycaster, intersects ) { - var intersect; + var geometry = this.geometry; + var material = this.material; + var matrixWorld = this.matrixWorld; - if ( material.side === BackSide ) { + if ( material === undefined ) return; - intersect = ray.intersectTriangle( pC, pB, pA, true, point ); + // Checking boundingSphere distance to ray - } else { + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); + _sphere.copy( geometry.boundingSphere ); + _sphere.applyMatrix4( matrixWorld ); - } + if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return; - if ( intersect === null ) return null; + // - intersectionPointWorld.copy( point ); - intersectionPointWorld.applyMatrix4( object.matrixWorld ); + _inverseMatrix.getInverse( matrixWorld ); + _ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix ); - var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld ); + // Check boundingBox before continuing - if ( distance < raycaster.near || distance > raycaster.far ) return null; + if ( geometry.boundingBox !== null ) { - return { - distance: distance, - point: intersectionPointWorld.clone(), - object: object - }; + if ( _ray.intersectsBox( geometry.boundingBox ) === false ) return; } - function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) { + var intersection; - vA.fromBufferAttribute( position, a ); - vB.fromBufferAttribute( position, b ); - vC.fromBufferAttribute( position, c ); - - var morphInfluences = object.morphTargetInfluences; + if ( geometry.isBufferGeometry ) { - if ( material.morphTargets && morphPosition && morphInfluences ) { + var a, b, c; + var index = geometry.index; + var position = geometry.attributes.position; + var morphPosition = geometry.morphAttributes.position; + var uv = geometry.attributes.uv; + var uv2 = geometry.attributes.uv2; + var groups = geometry.groups; + var drawRange = geometry.drawRange; + var i, j, il, jl; + var group, groupMaterial; + var start, end; - morphA.set( 0, 0, 0 ); - morphB.set( 0, 0, 0 ); - morphC.set( 0, 0, 0 ); + if ( index !== null ) { - for ( var i = 0, il = morphPosition.length; i < il; i ++ ) { + // indexed buffer geometry - var influence = morphInfluences[ i ]; - var morphAttribute = morphPosition[ i ]; + if ( Array.isArray( material ) ) { - if ( influence === 0 ) continue; + for ( i = 0, il = groups.length; i < il; i ++ ) { - tempA.fromBufferAttribute( morphAttribute, a ); - tempB.fromBufferAttribute( morphAttribute, b ); - tempC.fromBufferAttribute( morphAttribute, c ); + group = groups[ i ]; + groupMaterial = material[ group.materialIndex ]; - morphA.addScaledVector( tempA.sub( vA ), influence ); - morphB.addScaledVector( tempB.sub( vB ), influence ); - morphC.addScaledVector( tempC.sub( vC ), influence ); + start = Math.max( group.start, drawRange.start ); + end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); - } + for ( j = start, jl = end; j < jl; j += 3 ) { - vA.add( morphA ); - vB.add( morphB ); - vC.add( morphC ); + a = index.getX( j ); + b = index.getX( j + 1 ); + c = index.getX( j + 2 ); - } + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); - var intersection = checkIntersection( object, material, raycaster, ray, vA, vB, vC, intersectionPoint ); + if ( intersection ) { - if ( intersection ) { + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - if ( uv ) { + } - uvA.fromBufferAttribute( uv, a ); - uvB.fromBufferAttribute( uv, b ); - uvC.fromBufferAttribute( uv, c ); + } - intersection.uv = Triangle.getUV( intersectionPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() ); + } - } + } else { - if ( uv2 ) { + start = Math.max( 0, drawRange.start ); + end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); - uvA.fromBufferAttribute( uv2, a ); - uvB.fromBufferAttribute( uv2, b ); - uvC.fromBufferAttribute( uv2, c ); + for ( i = start, il = end; i < il; i += 3 ) { - intersection.uv2 = Triangle.getUV( intersectionPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() ); + a = index.getX( i ); + b = index.getX( i + 1 ); + c = index.getX( i + 2 ); - } + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); - var face = new Face3( a, b, c ); - Triangle.getNormal( vA, vB, vC, face.normal ); + if ( intersection ) { - intersection.face = face; + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics + intersects.push( intersection ); - } + } - return intersection; + } - } + } - return function raycast( raycaster, intersects ) { + } else if ( position !== undefined ) { - var geometry = this.geometry; - var material = this.material; - var matrixWorld = this.matrixWorld; + // non-indexed buffer geometry - if ( material === undefined ) return; + if ( Array.isArray( material ) ) { - // Checking boundingSphere distance to ray + for ( i = 0, il = groups.length; i < il; i ++ ) { - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + group = groups[ i ]; + groupMaterial = material[ group.materialIndex ]; - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); + start = Math.max( group.start, drawRange.start ); + end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + for ( j = start, jl = end; j < jl; j += 3 ) { - // + a = j; + b = j + 1; + c = j + 2; - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); - // Check boundingBox before continuing + if ( intersection ) { - if ( geometry.boundingBox !== null ) { + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - if ( ray.intersectsBox( geometry.boundingBox ) === false ) return; + } - } + } - var intersection; + } - if ( geometry.isBufferGeometry ) { + } else { - var a, b, c; - var index = geometry.index; - var position = geometry.attributes.position; - var morphPosition = geometry.morphAttributes.position; - var uv = geometry.attributes.uv; - var uv2 = geometry.attributes.uv2; - var groups = geometry.groups; - var drawRange = geometry.drawRange; - var i, j, il, jl; - var group, groupMaterial; - var start, end; + start = Math.max( 0, drawRange.start ); + end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); - if ( index !== null ) { + for ( i = start, il = end; i < il; i += 3 ) { - // indexed buffer geometry + a = i; + b = i + 1; + c = i + 2; - if ( Array.isArray( material ) ) { + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); - for ( i = 0, il = groups.length; i < il; i ++ ) { + if ( intersection ) { - group = groups[ i ]; - groupMaterial = material[ group.materialIndex ]; + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics + intersects.push( intersection ); - start = Math.max( group.start, drawRange.start ); - end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); - - for ( j = start, jl = end; j < jl; j += 3 ) { + } - a = index.getX( j ); - b = index.getX( j + 1 ); - c = index.getX( j + 2 ); + } - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ); + } - if ( intersection ) { + } - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; - intersects.push( intersection ); + } else if ( geometry.isGeometry ) { - } + var fvA, fvB, fvC; + var isMultiMaterial = Array.isArray( material ); - } + var vertices = geometry.vertices; + var faces = geometry.faces; + var uvs; - } + var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; + if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; - } else { + for ( var f = 0, fl = faces.length; f < fl; f ++ ) { - start = Math.max( 0, drawRange.start ); - end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); + var face = faces[ f ]; + var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; - for ( i = start, il = end; i < il; i += 3 ) { + if ( faceMaterial === undefined ) continue; - a = index.getX( i ); - b = index.getX( i + 1 ); - c = index.getX( i + 2 ); + fvA = vertices[ face.a ]; + fvB = vertices[ face.b ]; + fvC = vertices[ face.c ]; - intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint ); - if ( intersection ) { + if ( intersection ) { - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics - intersects.push( intersection ); + if ( uvs && uvs[ f ] ) { - } + var uvs_f = uvs[ f ]; + _uvA.copy( uvs_f[ 0 ] ); + _uvB.copy( uvs_f[ 1 ] ); + _uvC.copy( uvs_f[ 2 ] ); - } + intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() ); } - } else if ( position !== undefined ) { + intersection.face = face; + intersection.faceIndex = f; + intersects.push( intersection ); - // non-indexed buffer geometry + } - if ( Array.isArray( material ) ) { + } - for ( i = 0, il = groups.length; i < il; i ++ ) { + } - group = groups[ i ]; - groupMaterial = material[ group.materialIndex ]; + }, - start = Math.max( group.start, drawRange.start ); - end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); + clone: function () { - for ( j = start, jl = end; j < jl; j += 3 ) { + return new this.constructor( this.geometry, this.material ).copy( this ); - a = j; - b = j + 1; - c = j + 2; + } - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ); + } ); - if ( intersection ) { + function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; - intersects.push( intersection ); + var intersect; - } + if ( material.side === BackSide ) { - } + intersect = ray.intersectTriangle( pC, pB, pA, true, point ); - } + } else { - } else { + intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); - start = Math.max( 0, drawRange.start ); - end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); + } - for ( i = start, il = end; i < il; i += 3 ) { + if ( intersect === null ) return null; - a = i; - b = i + 1; - c = i + 2; + _intersectionPointWorld.copy( point ); + _intersectionPointWorld.applyMatrix4( object.matrixWorld ); - intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ); + var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); - if ( intersection ) { + if ( distance < raycaster.near || distance > raycaster.far ) return null; - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics - intersects.push( intersection ); + return { + distance: distance, + point: _intersectionPointWorld.clone(), + object: object + }; - } + } - } + function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) { - } + _vA.fromBufferAttribute( position, a ); + _vB.fromBufferAttribute( position, b ); + _vC.fromBufferAttribute( position, c ); - } + var morphInfluences = object.morphTargetInfluences; - } else if ( geometry.isGeometry ) { + if ( material.morphTargets && morphPosition && morphInfluences ) { - var fvA, fvB, fvC; - var isMultiMaterial = Array.isArray( material ); + _morphA.set( 0, 0, 0 ); + _morphB.set( 0, 0, 0 ); + _morphC.set( 0, 0, 0 ); - var vertices = geometry.vertices; - var faces = geometry.faces; - var uvs; + for ( var i = 0, il = morphPosition.length; i < il; i ++ ) { - var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; - if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; + var influence = morphInfluences[ i ]; + var morphAttribute = morphPosition[ i ]; - for ( var f = 0, fl = faces.length; f < fl; f ++ ) { + if ( influence === 0 ) continue; - var face = faces[ f ]; - var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; + _tempA.fromBufferAttribute( morphAttribute, a ); + _tempB.fromBufferAttribute( morphAttribute, b ); + _tempC.fromBufferAttribute( morphAttribute, c ); - if ( faceMaterial === undefined ) continue; + _morphA.addScaledVector( _tempA.sub( _vA ), influence ); + _morphB.addScaledVector( _tempB.sub( _vB ), influence ); + _morphC.addScaledVector( _tempC.sub( _vC ), influence ); - fvA = vertices[ face.a ]; - fvB = vertices[ face.b ]; - fvC = vertices[ face.c ]; + } - intersection = checkIntersection( this, faceMaterial, raycaster, ray, fvA, fvB, fvC, intersectionPoint ); + _vA.add( _morphA ); + _vB.add( _morphB ); + _vC.add( _morphC ); - if ( intersection ) { + } - if ( uvs && uvs[ f ] ) { + var intersection = checkIntersection( object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint ); - var uvs_f = uvs[ f ]; - uvA.copy( uvs_f[ 0 ] ); - uvB.copy( uvs_f[ 1 ] ); - uvC.copy( uvs_f[ 2 ] ); + if ( intersection ) { - intersection.uv = Triangle.getUV( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC, new Vector2() ); + if ( uv ) { - } + _uvA.fromBufferAttribute( uv, a ); + _uvB.fromBufferAttribute( uv, b ); + _uvC.fromBufferAttribute( uv, c ); - intersection.face = face; - intersection.faceIndex = f; - intersects.push( intersection ); + intersection.uv = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ); - } + } - } + if ( uv2 ) { - } + _uvA.fromBufferAttribute( uv2, a ); + _uvB.fromBufferAttribute( uv2, b ); + _uvC.fromBufferAttribute( uv2, c ); - }; + intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ); - }() ), + } - clone: function () { + var face = new Face3( a, b, c ); + Triangle.getNormal( _vA, _vB, _vC, face.normal ); - return new this.constructor( this.geometry, this.material ).copy( this ); + intersection.face = face; } - } ); + return intersection; + + } /** * @author mrdoob / http://mrdoob.com/ @@ -11485,11 +11209,14 @@ * @author bhouston / http://clara.io */ - var geometryId = 0; // Geometry uses even numbers as Id + var _geometryId = 0; // Geometry uses even numbers as Id + var _m1$3 = new Matrix4(); + var _obj$1 = new Object3D(); + var _offset$1 = new Vector3(); function Geometry() { - Object.defineProperty( this, 'id', { value: geometryId += 2 } ); + Object.defineProperty( this, 'id', { value: _geometryId += 2 } ); this.uuid = _Math.generateUUID(); @@ -11573,111 +11300,77 @@ }, - rotateX: function () { + rotateX: function ( angle ) { // rotate geometry around world x-axis - var m1 = new Matrix4(); - - return function rotateX( angle ) { + _m1$3.makeRotationX( angle ); - m1.makeRotationX( angle ); + this.applyMatrix( _m1$3 ); - this.applyMatrix( m1 ); - - return this; - - }; + return this; - }(), + }, - rotateY: function () { + rotateY: function ( angle ) { // rotate geometry around world y-axis - var m1 = new Matrix4(); - - return function rotateY( angle ) { + _m1$3.makeRotationY( angle ); - m1.makeRotationY( angle ); + this.applyMatrix( _m1$3 ); - this.applyMatrix( m1 ); - - return this; - - }; + return this; - }(), + }, - rotateZ: function () { + rotateZ: function ( angle ) { // rotate geometry around world z-axis - var m1 = new Matrix4(); - - return function rotateZ( angle ) { - - m1.makeRotationZ( angle ); + _m1$3.makeRotationZ( angle ); - this.applyMatrix( m1 ); + this.applyMatrix( _m1$3 ); - return this; - - }; + return this; - }(), + }, - translate: function () { + translate: function ( x, y, z ) { // translate geometry - var m1 = new Matrix4(); - - return function translate( x, y, z ) { - - m1.makeTranslation( x, y, z ); + _m1$3.makeTranslation( x, y, z ); - this.applyMatrix( m1 ); + this.applyMatrix( _m1$3 ); - return this; - - }; + return this; - }(), + }, - scale: function () { + scale: function ( x, y, z ) { // scale geometry - var m1 = new Matrix4(); - - return function scale( x, y, z ) { - - m1.makeScale( x, y, z ); - - this.applyMatrix( m1 ); - - return this; - - }; + _m1$3.makeScale( x, y, z ); - }(), + this.applyMatrix( _m1$3 ); - lookAt: function () { + return this; - var obj = new Object3D(); + }, - return function lookAt( vector ) { + lookAt: function ( vector ) { - obj.lookAt( vector ); + _obj$1.lookAt( vector ); - obj.updateMatrix(); + _obj$1.updateMatrix(); - this.applyMatrix( obj.matrix ); + this.applyMatrix( _obj$1.matrix ); - }; + return this; - }(), + }, fromBufferGeometry: function ( geometry ) { @@ -11814,21 +11507,15 @@ center: function () { - var offset = new Vector3(); - - return function center() { - - this.computeBoundingBox(); + this.computeBoundingBox(); - this.boundingBox.getCenter( offset ).negate(); + this.boundingBox.getCenter( _offset$1 ).negate(); - this.translate( offset.x, offset.y, offset.z ); + this.translate( _offset$1.x, _offset$1.y, _offset$1.z ); - return this; - - }; + return this; - }(), + }, normalize: function () { @@ -13918,6 +13605,10 @@ * @author bhouston / http://clara.io */ + var _vector1 = new Vector3(); + var _vector2 = new Vector3(); + var _normalMatrix = new Matrix3(); + function Plane( normal, constant ) { // normal is assumed to be normalized @@ -13958,24 +13649,17 @@ }, - setFromCoplanarPoints: function () { - - var v1 = new Vector3(); - var v2 = new Vector3(); + setFromCoplanarPoints: function ( a, b, c ) { - return function setFromCoplanarPoints( a, b, c ) { + var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize(); - var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize(); + // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? - // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? + this.setFromNormalAndCoplanarPoint( normal, a ); - this.setFromNormalAndCoplanarPoint( normal, a ); - - return this; - - }; + return this; - }(), + }, clone: function () { @@ -14038,50 +13722,44 @@ }, - intersectLine: function () { - - var v1 = new Vector3(); - - return function intersectLine( line, target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Plane: .intersectLine() target is now required' ); - target = new Vector3(); + intersectLine: function ( line, target ) { - } + if ( target === undefined ) { - var direction = line.delta( v1 ); + console.warn( 'THREE.Plane: .intersectLine() target is now required' ); + target = new Vector3(); - var denominator = this.normal.dot( direction ); + } - if ( denominator === 0 ) { + var direction = line.delta( _vector1 ); - // line is coplanar, return origin - if ( this.distanceToPoint( line.start ) === 0 ) { + var denominator = this.normal.dot( direction ); - return target.copy( line.start ); + if ( denominator === 0 ) { - } + // line is coplanar, return origin + if ( this.distanceToPoint( line.start ) === 0 ) { - // Unsure if this is the correct method to handle this case. - return undefined; + return target.copy( line.start ); } - var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; + // Unsure if this is the correct method to handle this case. + return undefined; + + } - if ( t < 0 || t > 1 ) { + var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; - return undefined; + if ( t < 0 || t > 1 ) { - } + return undefined; - return target.copy( direction ).multiplyScalar( t ).add( line.start ); + } - }; + return target.copy( direction ).multiplyScalar( t ).add( line.start ); - }(), + }, intersectsLine: function ( line ) { @@ -14119,26 +13797,19 @@ }, - applyMatrix4: function () { - - var v1 = new Vector3(); - var m1 = new Matrix3(); + applyMatrix4: function ( matrix, optionalNormalMatrix ) { - return function applyMatrix4( matrix, optionalNormalMatrix ) { + var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix ); - var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); + var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix ); - var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix ); + var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); - var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); + this.constant = - referencePoint.dot( normal ); - this.constant = - referencePoint.dot( normal ); - - return this; - - }; + return this; - }(), + }, translate: function ( offset ) { @@ -14162,6 +13833,9 @@ * @author bhouston / http://clara.io */ + var _sphere$1 = new Sphere(); + var _vector$5 = new Vector3(); + function Frustum( p0, p1, p2, p3, p4, p5 ) { this.planes = [ @@ -14234,41 +13908,27 @@ }, - intersectsObject: function () { - - var sphere = new Sphere(); + intersectsObject: function ( object ) { - return function intersectsObject( object ) { - - var geometry = object.geometry; - - if ( geometry.boundingSphere === null ) - geometry.computeBoundingSphere(); - - sphere.copy( geometry.boundingSphere ) - .applyMatrix4( object.matrixWorld ); - - return this.intersectsSphere( sphere ); - - }; + var geometry = object.geometry; - }(), + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - intersectsSprite: function () { + _sphere$1.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld ); - var sphere = new Sphere(); + return this.intersectsSphere( _sphere$1 ); - return function intersectsSprite( sprite ) { + }, - sphere.center.set( 0, 0, 0 ); - sphere.radius = 0.7071067811865476; - sphere.applyMatrix4( sprite.matrixWorld ); + intersectsSprite: function ( sprite ) { - return this.intersectsSphere( sphere ); + _sphere$1.center.set( 0, 0, 0 ); + _sphere$1.radius = 0.7071067811865476; + _sphere$1.applyMatrix4( sprite.matrixWorld ); - }; + return this.intersectsSphere( _sphere$1 ); - }(), + }, intersectsSphere: function ( sphere ) { @@ -14292,37 +13952,31 @@ }, - intersectsBox: function () { - - var p = new Vector3(); - - return function intersectsBox( box ) { - - var planes = this.planes; + intersectsBox: function ( box ) { - for ( var i = 0; i < 6; i ++ ) { + var planes = this.planes; - var plane = planes[ i ]; + for ( var i = 0; i < 6; i ++ ) { - // corner at max distance + var plane = planes[ i ]; - p.x = plane.normal.x > 0 ? box.max.x : box.min.x; - p.y = plane.normal.y > 0 ? box.max.y : box.min.y; - p.z = plane.normal.z > 0 ? box.max.z : box.min.z; + // corner at max distance - if ( plane.distanceToPoint( p ) < 0 ) { + _vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x; + _vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y; + _vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z; - return false; + if ( plane.distanceToPoint( _vector$5 ) < 0 ) { - } + return false; } - return true; + } - }; + return true; - }(), + }, containsPoint: function ( point ) { @@ -14350,7 +14004,7 @@ var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; - var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; + var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; @@ -14358,17 +14012,17 @@ var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; - var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}"; + var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif"; var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; - var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; + var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; - var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif"; + var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif"; - var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif"; + var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif"; var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; @@ -14378,7 +14032,7 @@ var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; - var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}"; + var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}"; var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif"; @@ -14396,19 +14050,21 @@ var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}"; - var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; + var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; - var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; + var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif"; - var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; + var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; - var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; + var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; + + var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; - var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; + var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; @@ -14422,21 +14078,21 @@ var lights_pars_begin = "uniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif"; - var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; + var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; - var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif"; + var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = saturate( clearcoat );\tmaterial.clearcoatRoughness = clamp( clearcoatRoughness, 0.04, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif"; - var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#endif\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\tfloat clearCoatInv = 1.0 - clearCoatDHR;\n\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec3 singleScattering = vec3( 0.0 );\n\t\tvec3 multiScattering = vec3( 0.0 );\n\t\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\t\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\t\treflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;\n\t\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\t\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n\t#else\n\t\treflectedLight.indirectSpecular += clearCoatInv * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#endif\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; + var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; - var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif"; + var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif"; - var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif"; + var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif"; - var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, irradiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif"; + var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif"; var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; @@ -14464,33 +14120,39 @@ var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; - var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif"; + var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;"; + + var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, normalScale, normalMap );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; + + var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec2 normalScale, in sampler2D normalMap ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvec3 NfromST = cross( S, T );\n\t\t\tif( dot( NfromST, N ) > 0.0 ) {\n\t\t\t\tS *= -1.0;\n\t\t\t\tT *= -1.0;\n\t\t\t}\n\t\t#else\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif"; - var normal_fragment_maps = "#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\t#ifdef USE_TANGENT\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy = normalScale * mapN.xy;\n\t\t\tnormal = normalize( vTBN * mapN );\n\t\t#else\n\t\t\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\t\t#endif\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; + var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; - var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#else\n\t\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\t\tvec2 st0 = dFdx( vUv.st );\n\t\t\tvec2 st1 = dFdy( vUv.st );\n\t\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\t\tvec3 N = normalize( surf_norm );\n\t\t\tmat3 tsn = mat3( S, T, N );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy *= normalScale;\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\treturn normalize( tsn * mapN );\n\t\t}\n\t#endif\n#endif"; + var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, clearcoatNormal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = clearcoatNormalScale * mapN.xy;\n\t\tclearcoatNormal = normalize( vTBN * mapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatNormalScale, clearcoatNormalMap );\n\t#endif\n#endif"; - var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; + var clearcoat_normalmap_pars_fragment = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif"; + + var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 encodeHalfRGBA ( vec2 v ) {\n\tvec4 encoded = vec4( 0.0 );\n\tconst vec2 offset = vec2( 1.0 / 255.0, 0.0 );\n\tencoded.xy = vec2( v.x, fract( v.x * 255.0 ) );\n\tencoded.xy = encoded.xy - ( encoded.yy * offset );\n\tencoded.zw = vec2( v.y, fract( v.y * 255.0 ) );\n\tencoded.zw = encoded.zw - ( encoded.ww * offset );\n\treturn encoded;\n}\nvec2 decodeHalfRGBA( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;"; - var dithering_fragment = "#if defined( DITHERING )\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; + var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; - var dithering_pars_fragment = "#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; + var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; - var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; + var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn decodeHalfRGBA( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; - var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif"; + var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif"; - var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif"; + var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif"; - var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}"; + var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}"; var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; @@ -14508,11 +14170,11 @@ var tonemapping_pars_fragment = "#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}"; - var uv_pars_fragment = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif"; + var uv_pars_fragment = "#ifdef USE_UV\n\tvarying vec2 vUv;\n#endif"; - var uv_pars_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif"; + var uv_pars_vertex = "#ifdef USE_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif"; - var uv_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; + var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; @@ -14546,11 +14208,11 @@ var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; - var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; @@ -14558,17 +14220,17 @@ var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}"; - var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSPARENCY\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSPARENCY\n\tuniform float transparency;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; + var meshphysical_vert = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; - var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; + var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; - var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; + var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; @@ -14610,6 +14272,7 @@ encodings_fragment: encodings_fragment, encodings_pars_fragment: encodings_pars_fragment, envmap_fragment: envmap_fragment, + envmap_common_pars_fragment: envmap_common_pars_fragment, envmap_pars_fragment: envmap_pars_fragment, envmap_pars_vertex: envmap_pars_vertex, envmap_physical_pars_fragment: envmap_physical_pars_fragment, @@ -14646,6 +14309,9 @@ normal_fragment_begin: normal_fragment_begin, normal_fragment_maps: normal_fragment_maps, normalmap_pars_fragment: normalmap_pars_fragment, + clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, + clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, + clearcoat_normalmap_pars_fragment: clearcoat_normalmap_pars_fragment, packing: packing, premultiplied_alpha_fragment: premultiplied_alpha_fragment, project_vertex: project_vertex, @@ -15169,8 +14835,12 @@ uniforms: mergeUniforms( [ ShaderLib.standard.uniforms, { - clearCoat: { value: 0 }, - clearCoatRoughness: { value: 0 } + transparency: { value: 0 }, + clearcoat: { value: 0 }, + clearcoatRoughness: { value: 0 }, + sheen: { value: new Color( 0x000000 ) }, + clearcoatNormalScale: { value: new Vector2( 1, 1 ) }, + clearcoatNormalMap: { value: null }, } ] ), @@ -15743,15 +15413,17 @@ function renderInstances( geometry, start, count ) { - var extension; + var extension, methodName; if ( capabilities.isWebGL2 ) { extension = gl; + methodName = 'drawArraysInstanced'; } else { extension = extensions.get( 'ANGLE_instanced_arrays' ); + methodName = 'drawArraysInstancedANGLE'; if ( extension === null ) { @@ -15762,7 +15434,7 @@ } - extension[ capabilities.isWebGL2 ? 'drawArraysInstanced' : 'drawArraysInstancedANGLE' ]( mode, start, count, geometry.maxInstancedCount ); + extension[ methodName ]( mode, start, count, geometry.maxInstancedCount ); info.update( count, mode, geometry.maxInstancedCount ); @@ -16118,13 +15790,13 @@ function WebGLGeometries( gl, attributes, info ) { - var geometries = {}; - var wireframeAttributes = {}; + var geometries = new WeakMap(); + var wireframeAttributes = new WeakMap(); function onGeometryDispose( event ) { var geometry = event.target; - var buffergeometry = geometries[ geometry.id ]; + var buffergeometry = geometries.get( geometry ); if ( buffergeometry.index !== null ) { @@ -16140,14 +15812,14 @@ geometry.removeEventListener( 'dispose', onGeometryDispose ); - delete geometries[ geometry.id ]; + geometries.delete( geometry ); - var attribute = wireframeAttributes[ buffergeometry.id ]; + var attribute = wireframeAttributes.get( buffergeometry ); if ( attribute ) { attributes.remove( attribute ); - delete wireframeAttributes[ buffergeometry.id ]; + wireframeAttributes.delete( buffergeometry ); } @@ -16159,7 +15831,7 @@ function get( object, geometry ) { - var buffergeometry = geometries[ geometry.id ]; + var buffergeometry = geometries.get( geometry ); if ( buffergeometry ) return buffergeometry; @@ -16181,7 +15853,7 @@ } - geometries[ geometry.id ] = buffergeometry; + geometries.set( geometry, buffergeometry ); info.memory.geometries ++; @@ -16271,19 +15943,19 @@ // - var previousAttribute = wireframeAttributes[ geometry.id ]; + var previousAttribute = wireframeAttributes.get( geometry ); if ( previousAttribute ) attributes.remove( previousAttribute ); // - wireframeAttributes[ geometry.id ] = attribute; + wireframeAttributes.set( geometry, attribute ); } function getWireframeAttribute( geometry ) { - var currentAttribute = wireframeAttributes[ geometry.id ]; + var currentAttribute = wireframeAttributes.get( geometry ); if ( currentAttribute ) { @@ -16307,7 +15979,7 @@ } - return wireframeAttributes[ geometry.id ]; + return wireframeAttributes.get( geometry ); } @@ -16355,15 +16027,17 @@ function renderInstances( geometry, start, count ) { - var extension; + var extension, methodName; if ( capabilities.isWebGL2 ) { extension = gl; + methodName = 'drawElementsInstanced'; } else { - var extension = extensions.get( 'ANGLE_instanced_arrays' ); + extension = extensions.get( 'ANGLE_instanced_arrays' ); + methodName = 'drawElementsInstancedANGLE'; if ( extension === null ) { @@ -16374,7 +16048,7 @@ } - extension[ capabilities.isWebGL2 ? 'drawElementsInstanced' : 'drawElementsInstancedANGLE' ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount ); + extension[ methodName ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount ); info.update( count, mode, geometry.maxInstancedCount ); @@ -17617,6 +17291,8 @@ return [ 'RGBD', '( value, 256.0 )' ]; case GammaEncoding: return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; + case LogLuvEncoding: + return [ 'LogLuv', '( value )' ]; default: throw new Error( 'unsupported encoding: ' + encoding ); @@ -17694,7 +17370,7 @@ extensions = extensions || {}; var chunks = [ - ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || ( parameters.normalMap && ! parameters.objectSpaceNormalMap ) || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', + ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', ( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '', ( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '', ( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '' @@ -17756,7 +17432,10 @@ .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights ) .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights ) .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights ) - .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights ); + .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights ) + .replace( /NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows ) + .replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows ) + .replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows ); } @@ -17800,7 +17479,9 @@ for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { - unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' ); + unroll += snippet + .replace( /\[ i \]/g, '[ ' + i + ' ]' ) + .replace( /UNROLLED_LOOP_INDEX/g, i ); } @@ -17831,6 +17512,10 @@ shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; + } else if ( parameters.shadowMapType === VSMShadowMap ) { + + shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; + } var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; @@ -17939,6 +17624,8 @@ 'precision ' + parameters.precision + ' float;', 'precision ' + parameters.precision + ' int;', + ( parameters.precision === 'highp' ) ? '#define HIGH_PRECISION' : '', + '#define SHADER_NAME ' + shader.name, customDefines, @@ -17949,7 +17636,7 @@ '#define MAX_BONES ' + parameters.maxBones, ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', - ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', + ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', @@ -17960,6 +17647,9 @@ parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', + ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', + + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', @@ -17968,6 +17658,7 @@ parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.vertexUvs ? '#define USE_UV' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', @@ -18053,6 +17744,8 @@ 'precision ' + parameters.precision + ' float;', 'precision ' + parameters.precision + ' int;', + ( parameters.precision === 'highp' ) ? '#define HIGH_PRECISION' : '', + '#define SHADER_NAME ' + shader.name, customDefines, @@ -18062,7 +17755,7 @@ '#define GAMMA_FACTOR ' + gammaFactorDefine, ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', - ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', + ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.matcap ? '#define USE_MATCAP' : '', @@ -18076,13 +17769,18 @@ parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', + ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', + parameters.sheen ? '#define USE_SHEEN' : '', + parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.vertexUvs ? '#define USE_UV' : '', parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', @@ -18101,7 +17799,7 @@ parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', - parameters.envMap && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '', + ( ( material.extensions ? material.extensions.shaderTextureLOD : false ) || parameters.envMap ) && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '', 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', @@ -18356,15 +18054,16 @@ var parameterNames = [ "precision", "supportsVertexTextures", "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", - "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "displacementMap", "specularMap", + "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatNormalMap", "displacementMap", "specularMap", "roughnessMap", "metalnessMap", "gradientMap", - "alphaMap", "combine", "vertexColors", "vertexTangents", "fog", "useFog", "fogExp", + "alphaMap", "combine", "vertexColors", "vertexTangents", "fog", "useFog", "fogExp2", "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", "maxBones", "useVertexTexture", "morphTargets", "morphNormals", "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', - "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering" + "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering", + "sheen" ]; @@ -18480,6 +18179,8 @@ bumpMap: !! material.bumpMap, normalMap: !! material.normalMap, objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, + tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, + clearcoatNormalMap: !! material.clearcoatNormalMap, displacementMap: !! material.displacementMap, roughnessMap: !! material.roughnessMap, metalnessMap: !! material.metalnessMap, @@ -18488,14 +18189,17 @@ gradientMap: !! material.gradientMap, + sheen: !! material.sheen, + combine: material.combine, vertexTangents: ( material.normalMap && material.vertexTangents ), vertexColors: material.vertexColors, + vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap, fog: !! fog, useFog: material.fog, - fogExp: ( fog && fog.isFogExp2 ), + fogExp2: ( fog && fog.isFogExp2 ), flatShading: material.flatShading, @@ -18517,6 +18221,10 @@ numRectAreaLights: lights.rectArea.length, numHemiLights: lights.hemi.length, + numDirLightShadows: lights.directionalShadowMap.length, + numPointLightShadows: lights.pointShadowMap.length, + numSpotLightShadows: lights.spotShadowMap.length, + numClippingPlanes: nClipPlanes, numClipIntersection: nClipIntersection, @@ -18525,7 +18233,7 @@ shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && shadows.length > 0, shadowMapType: renderer.shadowMap.type, - toneMapping: renderer.toneMapping, + toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, physicallyCorrectLights: renderer.physicallyCorrectLights, premultipliedAlpha: material.premultipliedAlpha, @@ -18840,7 +18548,7 @@ function WebGLRenderLists() { - var lists = {}; + var lists = new WeakMap(); function onSceneDispose( event ) { @@ -18848,29 +18556,29 @@ scene.removeEventListener( 'dispose', onSceneDispose ); - delete lists[ scene.id ]; + lists.delete( scene ); } function get( scene, camera ) { - var cameras = lists[ scene.id ]; + var cameras = lists.get( scene ); var list; if ( cameras === undefined ) { list = new WebGLRenderList(); - lists[ scene.id ] = {}; - lists[ scene.id ][ camera.id ] = list; + lists.set( scene, new WeakMap() ); + lists.get( scene ).set( camera, list ); scene.addEventListener( 'dispose', onSceneDispose ); } else { - list = cameras[ camera.id ]; + list = cameras.get( camera ); if ( list === undefined ) { list = new WebGLRenderList(); - cameras[ camera.id ] = list; + cameras.set( camera, list ); } @@ -18882,7 +18590,7 @@ function dispose() { - lists = {}; + lists = new WeakMap(); } @@ -18992,6 +18700,12 @@ var nextVersion = 0; + function shadowCastingLightsFirst( lightA, lightB ) { + + return ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 ); + + } + function WebGLLights() { var cache = new UniformsCache(); @@ -19006,7 +18720,10 @@ spotLength: - 1, rectAreaLength: - 1, hemiLength: - 1, - shadowsLength: - 1, + + numDirectionalShadows: - 1, + numPointShadows: - 1, + numSpotShadows: - 1, }, ambient: [ 0, 0, 0 ], @@ -19021,7 +18738,11 @@ point: [], pointShadowMap: [], pointShadowMatrix: [], - hemi: [] + hemi: [], + + numDirectionalShadows: - 1, + numPointShadows: - 1, + numSpotShadows: - 1 }; @@ -19043,8 +18764,14 @@ var rectAreaLength = 0; var hemiLength = 0; + var numDirectionalShadows = 0; + var numPointShadows = 0; + var numSpotShadows = 0; + var viewMatrix = camera.matrixWorldInverse; + lights.sort( shadowCastingLightsFirst ); + for ( var i = 0, l = lights.length; i < l; i ++ ) { var light = lights[ i ]; @@ -19089,10 +18816,13 @@ uniforms.shadowRadius = shadow.radius; uniforms.shadowMapSize = shadow.mapSize; + state.directionalShadowMap[ directionalLength ] = shadowMap; + state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; + + numDirectionalShadows ++; + } - state.directionalShadowMap[ directionalLength ] = shadowMap; - state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; state.directional[ directionalLength ] = uniforms; directionalLength ++; @@ -19126,10 +18856,13 @@ uniforms.shadowRadius = shadow.radius; uniforms.shadowMapSize = shadow.mapSize; + state.spotShadowMap[ spotLength ] = shadowMap; + state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; + + numSpotShadows ++; + } - state.spotShadowMap[ spotLength ] = shadowMap; - state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; state.spot[ spotLength ] = uniforms; spotLength ++; @@ -19189,10 +18922,13 @@ uniforms.shadowCameraNear = shadow.camera.near; uniforms.shadowCameraFar = shadow.camera.far; + state.pointShadowMap[ pointLength ] = shadowMap; + state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; + + numPointShadows ++; + } - state.pointShadowMap[ pointLength ] = shadowMap; - state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; state.point[ pointLength ] = uniforms; pointLength ++; @@ -19227,7 +18963,9 @@ hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || - hash.shadowsLength !== shadows.length ) { + hash.numDirectionalShadows !== numDirectionalShadows || + hash.numPointShadows !== numPointShadows || + hash.numSpotShadows !== numSpotShadows ) { state.directional.length = directionalLength; state.spot.length = spotLength; @@ -19235,12 +18973,22 @@ state.point.length = pointLength; state.hemi.length = hemiLength; + state.directionalShadowMap.length = numDirectionalShadows; + state.pointShadowMap.length = numPointShadows; + state.spotShadowMap.length = numSpotShadows; + state.directionalShadowMatrix.length = numDirectionalShadows; + state.pointShadowMatrix.length = numPointShadows; + state.spotShadowMatrix.length = numSpotShadows; + hash.directionalLength = directionalLength; hash.pointLength = pointLength; hash.spotLength = spotLength; hash.rectAreaLength = rectAreaLength; hash.hemiLength = hemiLength; - hash.shadowsLength = shadows.length; + + hash.numDirectionalShadows = numDirectionalShadows; + hash.numPointShadows = numPointShadows; + hash.numSpotShadows = numSpotShadows; state.version = nextVersion ++; @@ -19311,7 +19059,7 @@ function WebGLRenderStates() { - var renderStates = {}; + var renderStates = new WeakMap(); function onSceneDispose( event ) { @@ -19319,7 +19067,7 @@ scene.removeEventListener( 'dispose', onSceneDispose ); - delete renderStates[ scene.id ]; + renderStates.delete( scene ); } @@ -19327,24 +19075,24 @@ var renderState; - if ( renderStates[ scene.id ] === undefined ) { + if ( renderStates.has( scene ) === false ) { renderState = new WebGLRenderState(); - renderStates[ scene.id ] = {}; - renderStates[ scene.id ][ camera.id ] = renderState; + renderStates.set( scene, new WeakMap() ); + renderStates.get( scene ).set( camera, renderState ); scene.addEventListener( 'dispose', onSceneDispose ); } else { - if ( renderStates[ scene.id ][ camera.id ] === undefined ) { + if ( renderStates.get( scene ).has( camera ) === false ) { renderState = new WebGLRenderState(); - renderStates[ scene.id ][ camera.id ] = renderState; + renderStates.get( scene ).set( camera, renderState ); } else { - renderState = renderStates[ scene.id ][ camera.id ]; + renderState = renderStates.get( scene ).get( camera ); } @@ -19356,7 +19104,7 @@ function dispose() { - renderStates = {}; + renderStates = new WeakMap(); } @@ -19527,6 +19275,10 @@ }; + var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include \nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n \n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = decodeHalfRGBA ( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = pow( squared_mean - mean * mean, 0.5 );\n gl_FragColor = encodeHalfRGBA( vec2( mean, std_dev ) );\n}"; + + var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; + /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ @@ -19535,13 +19287,11 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { var _frustum = new Frustum(), - _projScreenMatrix = new Matrix4(), _shadowMapSize = new Vector2(), - _maxShadowMapSize = new Vector2( maxTextureSize, maxTextureSize ), + _viewportSize = new Vector2(), - _lookTarget = new Vector3(), - _lightPositionWorld = new Vector3(), + _viewport = new Vector4(), _MorphingFlag = 1, _SkinningFlag = 2, @@ -19555,20 +19305,38 @@ var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; - var cubeDirections = [ - new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), - new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) - ]; + var shadowMaterialVertical = new ShaderMaterial( { - var cubeUps = [ - new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), - new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) - ]; + defines: { + SAMPLE_RATE: 2.0 / 8.0, + HALF_SAMPLE_RATE: 1.0 / 8.0 + }, - var cube2DViewPorts = [ - new Vector4(), new Vector4(), new Vector4(), - new Vector4(), new Vector4(), new Vector4() - ]; + uniforms: { + shadow_pass: { value: null }, + resolution: { value: new Vector2() }, + radius: { value: 4.0 } + }, + + vertexShader: vsm_vert, + + fragmentShader: vsm_frag + + } ); + + var shadowMaterialHorizonal = shadowMaterialVertical.clone(); + shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1; + + var fullScreenTri = new BufferGeometry(); + fullScreenTri.addAttribute( + "position", + new BufferAttribute( + new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ), + 3 + ) + ); + + var fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical ); // init @@ -19588,8 +19356,6 @@ _depthMaterials[ i ] = depthMaterial; - // - var distanceMaterial = new MeshDistanceMaterial( { morphTargets: useMorphing, @@ -19601,8 +19367,6 @@ } - // - var scope = this; this.enabled = false; @@ -19633,13 +19397,10 @@ // render depth map - var faceCount; - for ( var i = 0, il = lights.length; i < il; i ++ ) { var light = lights[ i ]; var shadow = light.shadow; - var isPointLight = light && light.isPointLight; if ( shadow === undefined ) { @@ -19648,130 +19409,91 @@ } - var shadowCamera = shadow.camera; - _shadowMapSize.copy( shadow.mapSize ); - _shadowMapSize.min( _maxShadowMapSize ); - if ( isPointLight ) { + var shadowFrameExtents = shadow.getFrameExtents(); - var vpWidth = _shadowMapSize.x; - var vpHeight = _shadowMapSize.y; + _shadowMapSize.multiply( shadowFrameExtents ); - // These viewports map a cube-map onto a 2D texture with the - // following orientation: - // - // xzXZ - // y Y - // - // X - Positive x direction - // x - Negative x direction - // Y - Positive y direction - // y - Negative y direction - // Z - Positive z direction - // z - Negative z direction - - // positive X - cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight ); - // negative X - cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight ); - // positive Z - cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight ); - // negative Z - cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight ); - // positive Y - cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight ); - // negative Y - cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight ); - - _shadowMapSize.x *= 4.0; - _shadowMapSize.y *= 2.0; + _viewportSize.copy( shadow.mapSize ); - } + if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) { - if ( shadow.map === null ) { + console.warn( 'THREE.WebGLShadowMap:', light, 'has shadow exceeding max texture size, reducing' ); - var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; + if ( _shadowMapSize.x > maxTextureSize ) { - shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); - shadow.map.texture.name = light.name + ".shadowMap"; + _viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x ); + _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; + shadow.mapSize.x = _viewportSize.x; - shadowCamera.updateProjectionMatrix(); + } - } + if ( _shadowMapSize.y > maxTextureSize ) { - if ( shadow.isSpotLightShadow ) { + _viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y ); + _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; + shadow.mapSize.y = _viewportSize.y; - shadow.update( light ); + } } - var shadowMap = shadow.map; - var shadowMatrix = shadow.matrix; - - _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); - shadowCamera.position.copy( _lightPositionWorld ); + if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { - if ( isPointLight ) { + var pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat }; - faceCount = 6; + shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + shadow.map.texture.name = light.name + ".shadowMap"; - // for point lights we set the shadow matrix to be a translation-only matrix - // equal to inverse of the light's position + shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); - shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z ); + shadow.camera.updateProjectionMatrix(); - } else { - - faceCount = 1; + } - _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + if ( shadow.map === null ) { - // compute shadow matrix + var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; - shadowMatrix.set( - 0.5, 0.0, 0.0, 0.5, - 0.0, 0.5, 0.0, 0.5, - 0.0, 0.0, 0.5, 0.5, - 0.0, 0.0, 0.0, 1.0 - ); + shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + shadow.map.texture.name = light.name + ".shadowMap"; - shadowMatrix.multiply( shadowCamera.projectionMatrix ); - shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + shadow.camera.updateProjectionMatrix(); } - _renderer.setRenderTarget( shadowMap ); + _renderer.setRenderTarget( shadow.map ); _renderer.clear(); - // render shadow map for each cube face (if omni-directional) or - // run a single pass if not + var viewportCount = shadow.getViewportCount(); - for ( var face = 0; face < faceCount; face ++ ) { + for ( var vp = 0; vp < viewportCount; vp ++ ) { - if ( isPointLight ) { + var viewport = shadow.getViewport( vp ); - _lookTarget.copy( shadowCamera.position ); - _lookTarget.add( cubeDirections[ face ] ); - shadowCamera.up.copy( cubeUps[ face ] ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + _viewport.set( + _viewportSize.x * viewport.x, + _viewportSize.y * viewport.y, + _viewportSize.x * viewport.z, + _viewportSize.y * viewport.w + ); - var vpDimensions = cube2DViewPorts[ face ]; - _state.viewport( vpDimensions ); + _state.viewport( _viewport ); - } + shadow.updateMatrices( light, camera, vp ); - // update camera matrices and frustum + _frustum = shadow.getFrustum(); - _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); + renderObject( scene, camera, shadow.camera, light, this.type ); + + } - // set object matrices & frustum culling + // do blur pass for VSM - renderObject( scene, camera, shadowCamera, isPointLight ); + if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { + + VSMPass( shadow, camera ); } @@ -19783,7 +19505,31 @@ }; - function getDepthMaterial( object, material, isPointLight, lightPositionWorld, shadowCameraNear, shadowCameraFar ) { + function VSMPass( shadow, camera ) { + + var geometry = _objects.update( fullScreenMesh ); + + // vertical pass + + shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; + shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; + shadowMaterialVertical.uniforms.radius.value = shadow.radius; + _renderer.setRenderTarget( shadow.mapPass ); + _renderer.clear(); + _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null ); + + // horizonal pass + + shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture; + shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize; + shadowMaterialHorizonal.uniforms.radius.value = shadow.radius; + _renderer.setRenderTarget( shadow.map ); + _renderer.clear(); + _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null ); + + } + + function getDepthMaterial( object, material, light, shadowCameraNear, shadowCameraFar, type ) { var geometry = object.geometry; @@ -19792,7 +19538,7 @@ var materialVariants = _depthMaterials; var customMaterial = object.customDepthMaterial; - if ( isPointLight ) { + if ( light.isPointLight ) { materialVariants = _distanceMaterials; customMaterial = object.customDistanceMaterial; @@ -19872,7 +19618,15 @@ result.visible = material.visible; result.wireframe = material.wireframe; - result.side = ( material.shadowSide != null ) ? material.shadowSide : shadowSide[ material.side ]; + if ( type === VSMShadowMap ) { + + result.side = ( material.shadowSide != null ) ? material.shadowSide : material.side; + + } else { + + result.side = ( material.shadowSide != null ) ? material.shadowSide : shadowSide[ material.side ]; + + } result.clipShadows = material.clipShadows; result.clippingPlanes = material.clippingPlanes; @@ -19881,9 +19635,9 @@ result.wireframeLinewidth = material.wireframeLinewidth; result.linewidth = material.linewidth; - if ( isPointLight && result.isMeshDistanceMaterial ) { + if ( light.isPointLight && result.isMeshDistanceMaterial ) { - result.referencePosition.copy( lightPositionWorld ); + result.referencePosition.setFromMatrixPosition( light.matrixWorld ); result.nearDistance = shadowCameraNear; result.farDistance = shadowCameraFar; @@ -19893,7 +19647,7 @@ } - function renderObject( object, camera, shadowCamera, isPointLight ) { + function renderObject( object, camera, shadowCamera, light, type ) { if ( object.visible === false ) return; @@ -19901,7 +19655,7 @@ if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { - if ( object.castShadow && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { + if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); @@ -19919,7 +19673,8 @@ if ( groupMaterial && groupMaterial.visible ) { - var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); + var depthMaterial = getDepthMaterial( object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); } @@ -19928,7 +19683,8 @@ } else if ( material.visible ) { - var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); + var depthMaterial = getDepthMaterial( object, material, light, shadowCamera.near, shadowCamera.far, type ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); } @@ -19941,7 +19697,7 @@ for ( var i = 0, l = children.length; i < l; i ++ ) { - renderObject( children[ i ], camera, shadowCamera, isPointLight ); + renderObject( children[ i ], camera, shadowCamera, light, type ); } @@ -20163,13 +19919,17 @@ setTest: function ( stencilTest ) { - if ( stencilTest ) { + if ( ! locked ) { - enable( 2960 ); + if ( stencilTest ) { - } else { + enable( 2960 ); + + } else { - disable( 2960 ); + disable( 2960 ); + + } } @@ -20937,7 +20697,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { - var _videoTextures = {}; + var _videoTextures = new WeakMap(); var _canvas; // @@ -21119,7 +20879,7 @@ if ( texture.isVideoTexture ) { - delete _videoTextures[ texture.id ]; + _videoTextures.delete( texture ); } @@ -21287,120 +21047,137 @@ function setTextureCube( texture, slot ) { + if ( texture.image.length !== 6 ) return; + var textureProperties = properties.get( texture ); - if ( texture.image.length === 6 ) { + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { - if ( texture.version > 0 && textureProperties.__version !== texture.version ) { + initTexture( textureProperties, texture ); - initTexture( textureProperties, texture ); + state.activeTexture( 33984 + slot ); + state.bindTexture( 34067, textureProperties.__webglTexture ); - state.activeTexture( 33984 + slot ); - state.bindTexture( 34067, textureProperties.__webglTexture ); + _gl.pixelStorei( 37440, texture.flipY ); - _gl.pixelStorei( 37440, texture.flipY ); + var isCompressed = ( texture && texture.isCompressedTexture ); + var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); - var isCompressed = ( texture && texture.isCompressedTexture ); - var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); + var cubeImage = []; - var cubeImage = []; + for ( var i = 0; i < 6; i ++ ) { - for ( var i = 0; i < 6; i ++ ) { + if ( ! isCompressed && ! isDataTexture ) { - if ( ! isCompressed && ! isDataTexture ) { + cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, capabilities.maxCubemapSize ); - cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, capabilities.maxCubemapSize ); + } else { - } else { + cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; - cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; + } - } + } - } + var image = cubeImage[ 0 ], + supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2, + glFormat = utils.convert( texture.format ), + glType = utils.convert( texture.type ), + glInternalFormat = getInternalFormat( glFormat, glType ); + + setTextureParameters( 34067, texture, supportsMips ); - var image = cubeImage[ 0 ], - supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2, - glFormat = utils.convert( texture.format ), - glType = utils.convert( texture.type ), - glInternalFormat = getInternalFormat( glFormat, glType ); + var mipmaps; - setTextureParameters( 34067, texture, supportsMips ); + if ( isCompressed ) { for ( var i = 0; i < 6; i ++ ) { - if ( ! isCompressed ) { + mipmaps = cubeImage[ i ].mipmaps; - if ( isDataTexture ) { + for ( var j = 0; j < mipmaps.length; j ++ ) { - state.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); + var mipmap = mipmaps[ j ]; - } else { + if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { - state.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); + if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { - } + state.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); - } else { + } else { - var mipmap, mipmaps = cubeImage[ i ].mipmaps; + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); - for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) { + } - mipmap = mipmaps[ j ]; + } else { - if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { + state.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { + } - state.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + } - } else { + } - console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); + textureProperties.__maxMipLevel = mipmaps.length - 1; - } + } else { - } else { + mipmaps = texture.mipmaps; - state.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + for ( var i = 0; i < 6; i ++ ) { - } + if ( isDataTexture ) { - } + state.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); - } + for ( var j = 0; j < mipmaps.length; j ++ ) { - } + var mipmap = mipmaps[ j ]; + var mipmapImage = mipmap.image[ i ].image; - if ( ! isCompressed ) { + state.texImage2D( 34069 + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data ); - textureProperties.__maxMipLevel = 0; + } - } else { + } else { - textureProperties.__maxMipLevel = mipmaps.length - 1; + state.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); - } + for ( var j = 0; j < mipmaps.length; j ++ ) { - if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { + var mipmap = mipmaps[ j ]; - // We assume images for cube map have the same size. - generateMipmap( 34067, texture, image.width, image.height ); + state.texImage2D( 34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); + + } + + } } - textureProperties.__version = texture.version; + textureProperties.__maxMipLevel = mipmaps.length; - if ( texture.onUpdate ) texture.onUpdate( texture ); + } - } else { + if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { - state.activeTexture( 33984 + slot ); - state.bindTexture( 34067, textureProperties.__webglTexture ); + // We assume images for cube map have the same size. + generateMipmap( 34067, texture, image.width, image.height ); } + textureProperties.__version = texture.version; + + if ( texture.onUpdate ) texture.onUpdate( texture ); + + } else { + + state.activeTexture( 33984 + slot ); + state.bindTexture( 34067, textureProperties.__webglTexture ); + } } @@ -22017,14 +21794,13 @@ function updateVideoTexture( texture ) { - var id = texture.id; var frame = info.render.frame; // Check the last frame we updated the VideoTexture - if ( _videoTextures[ id ] !== frame ) { + if ( _videoTextures.get( texture ) !== frame ) { - _videoTextures[ id ] = frame; + _videoTextures.set( texture, frame ); texture.update(); } @@ -23116,8 +22892,6 @@ function WebGLRenderer( parameters ) { - console.log( 'THREE.WebGLRenderer', REVISION ); - parameters = parameters || {}; var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ), @@ -25334,8 +25108,24 @@ uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common - uniforms.clearCoat.value = material.clearCoat; - uniforms.clearCoatRoughness.value = material.clearCoatRoughness; + uniforms.clearcoat.value = material.clearcoat; + uniforms.clearcoatRoughness.value = material.clearcoatRoughness; + if ( material.sheen ) uniforms.sheen.value.copy( material.sheen ); + + if ( material.clearcoatNormalMap ) { + + uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale ); + uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; + + if ( material.side === BackSide ) { + + uniforms.clearcoatNormalScale.value.negate(); + + } + + } + + uniforms.transparency.value = material.transparency; } @@ -26033,7 +25823,23 @@ * @author alteredq / http://alteredqualia.com/ */ - var geometry; + var _geometry; + + var _intersectPoint = new Vector3(); + var _worldScale = new Vector3(); + var _mvPosition = new Vector3(); + + var _alignedPosition = new Vector2(); + var _rotatedPosition = new Vector2(); + var _viewWorldMatrix = new Matrix4(); + + var _vA$1 = new Vector3(); + var _vB$1 = new Vector3(); + var _vC$1 = new Vector3(); + + var _uvA$1 = new Vector2(); + var _uvB$1 = new Vector2(); + var _uvC$1 = new Vector2(); function Sprite( material ) { @@ -26041,9 +25847,9 @@ this.type = 'Sprite'; - if ( geometry === undefined ) { + if ( _geometry === undefined ) { - geometry = new BufferGeometry(); + _geometry = new BufferGeometry(); var float32Array = new Float32Array( [ - 0.5, - 0.5, 0, 0, 0, @@ -26054,13 +25860,13 @@ var interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); - geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); - geometry.addAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); - geometry.addAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); + _geometry.addAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); + _geometry.addAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); } - this.geometry = geometry; + this.geometry = _geometry; this.material = ( material !== undefined ) ? material : new SpriteMaterial(); this.center = new Vector2( 0.5, 0.5 ); @@ -26073,120 +25879,79 @@ isSprite: true, - raycast: ( function () { - - var intersectPoint = new Vector3(); - var worldScale = new Vector3(); - var mvPosition = new Vector3(); - - var alignedPosition = new Vector2(); - var rotatedPosition = new Vector2(); - var viewWorldMatrix = new Matrix4(); - - var vA = new Vector3(); - var vB = new Vector3(); - var vC = new Vector3(); - - var uvA = new Vector2(); - var uvB = new Vector2(); - var uvC = new Vector2(); + raycast: function ( raycaster, intersects ) { - function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { + if ( raycaster.camera === null ) { - // compute position in camera space - alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); + console.error( 'THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' ); - // to check if rotation is not zero - if ( sin !== undefined ) { - - rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y ); - rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y ); - - } else { + } - rotatedPosition.copy( alignedPosition ); + _worldScale.setFromMatrixScale( this.matrixWorld ); - } + _viewWorldMatrix.copy( raycaster.camera.matrixWorld ); + this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld ); + _mvPosition.setFromMatrixPosition( this.modelViewMatrix ); - vertexPosition.copy( mvPosition ); - vertexPosition.x += rotatedPosition.x; - vertexPosition.y += rotatedPosition.y; + if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) { - // transform to world space - vertexPosition.applyMatrix4( viewWorldMatrix ); + _worldScale.multiplyScalar( - _mvPosition.z ); } - return function raycast( raycaster, intersects ) { - - worldScale.setFromMatrixScale( this.matrixWorld ); - - viewWorldMatrix.copy( raycaster._camera.matrixWorld ); - this.modelViewMatrix.multiplyMatrices( raycaster._camera.matrixWorldInverse, this.matrixWorld ); - - mvPosition.setFromMatrixPosition( this.modelViewMatrix ); - - if ( raycaster._camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) { + var rotation = this.material.rotation; + var sin, cos; + if ( rotation !== 0 ) { - worldScale.multiplyScalar( - mvPosition.z ); + cos = Math.cos( rotation ); + sin = Math.sin( rotation ); - } - - var rotation = this.material.rotation; - var sin, cos; - if ( rotation !== 0 ) { + } - cos = Math.cos( rotation ); - sin = Math.sin( rotation ); + var center = this.center; - } + transformVertex( _vA$1.set( - 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + transformVertex( _vB$1.set( 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + transformVertex( _vC$1.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - var center = this.center; + _uvA$1.set( 0, 0 ); + _uvB$1.set( 1, 0 ); + _uvC$1.set( 1, 1 ); - transformVertex( vA.set( - 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); - transformVertex( vB.set( 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); - transformVertex( vC.set( 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); + // check first triangle + var intersect = raycaster.ray.intersectTriangle( _vA$1, _vB$1, _vC$1, false, _intersectPoint ); - uvA.set( 0, 0 ); - uvB.set( 1, 0 ); - uvC.set( 1, 1 ); + if ( intersect === null ) { - // check first triangle - var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint ); + // check second triangle + transformVertex( _vB$1.set( - 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + _uvB$1.set( 0, 1 ); + intersect = raycaster.ray.intersectTriangle( _vA$1, _vC$1, _vB$1, false, _intersectPoint ); if ( intersect === null ) { - // check second triangle - transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); - uvB.set( 0, 1 ); - - intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint ); - if ( intersect === null ) { - - return; - - } + return; } - var distance = raycaster.ray.origin.distanceTo( intersectPoint ); + } - if ( distance < raycaster.near || distance > raycaster.far ) return; + var distance = raycaster.ray.origin.distanceTo( _intersectPoint ); - intersects.push( { + if ( distance < raycaster.near || distance > raycaster.far ) return; - distance: distance, - point: intersectPoint.clone(), - uv: Triangle.getUV( intersectPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() ), - face: null, - object: this + intersects.push( { - } ); + distance: distance, + point: _intersectPoint.clone(), + uv: Triangle.getUV( _intersectPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ), + face: null, + object: this - }; + } ); - }() ), + }, clone: function () { @@ -26207,12 +25972,42 @@ } ); + function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { + + // compute position in camera space + _alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); + + // to check if rotation is not zero + if ( sin !== undefined ) { + + _rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y ); + _rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y ); + + } else { + + _rotatedPosition.copy( _alignedPosition ); + + } + + + vertexPosition.copy( mvPosition ); + vertexPosition.x += _rotatedPosition.x; + vertexPosition.y += _rotatedPosition.y; + + // transform to world space + vertexPosition.applyMatrix4( _viewWorldMatrix ); + + } + /** * @author mikael emtinger / http://gomo.se/ * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ */ + var _v1$4 = new Vector3(); + var _v2$2 = new Vector3(); + function LOD() { Object3D.call( this ); @@ -26298,66 +26093,53 @@ }, - raycast: ( function () { - - var matrixPosition = new Vector3(); + raycast: function ( raycaster, intersects ) { - return function raycast( raycaster, intersects ) { + _v1$4.setFromMatrixPosition( this.matrixWorld ); - matrixPosition.setFromMatrixPosition( this.matrixWorld ); + var distance = raycaster.ray.origin.distanceTo( _v1$4 ); - var distance = raycaster.ray.origin.distanceTo( matrixPosition ); + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); - this.getObjectForDistance( distance ).raycast( raycaster, intersects ); - - }; - - }() ), - - update: function () { - - var v1 = new Vector3(); - var v2 = new Vector3(); - - return function update( camera ) { + }, - var levels = this.levels; + update: function ( camera ) { - if ( levels.length > 1 ) { + var levels = this.levels; - v1.setFromMatrixPosition( camera.matrixWorld ); - v2.setFromMatrixPosition( this.matrixWorld ); + if ( levels.length > 1 ) { - var distance = v1.distanceTo( v2 ); + _v1$4.setFromMatrixPosition( camera.matrixWorld ); + _v2$2.setFromMatrixPosition( this.matrixWorld ); - levels[ 0 ].object.visible = true; + var distance = _v1$4.distanceTo( _v2$2 ); - for ( var i = 1, l = levels.length; i < l; i ++ ) { + levels[ 0 ].object.visible = true; - if ( distance >= levels[ i ].distance ) { + for ( var i = 1, l = levels.length; i < l; i ++ ) { - levels[ i - 1 ].object.visible = false; - levels[ i ].object.visible = true; + if ( distance >= levels[ i ].distance ) { - } else { + levels[ i - 1 ].object.visible = false; + levels[ i ].object.visible = true; - break; + } else { - } + break; } - for ( ; i < l; i ++ ) { + } - levels[ i ].object.visible = false; + for ( ; i < l; i ++ ) { - } + levels[ i ].object.visible = false; } - }; + } - }(), + }, toJSON: function ( meta ) { @@ -26505,6 +26287,9 @@ * @author ikerr / http://verold.com */ + var _offsetMatrix = new Matrix4(); + var _identityMatrix = new Matrix4(); + function Skeleton( bones, boneInverses ) { // copy the bone array @@ -26611,40 +26396,33 @@ }, - update: ( function () { - - var offsetMatrix = new Matrix4(); - var identityMatrix = new Matrix4(); - - return function update() { - - var bones = this.bones; - var boneInverses = this.boneInverses; - var boneMatrices = this.boneMatrices; - var boneTexture = this.boneTexture; + update: function () { - // flatten bone matrices to array + var bones = this.bones; + var boneInverses = this.boneInverses; + var boneMatrices = this.boneMatrices; + var boneTexture = this.boneTexture; - for ( var i = 0, il = bones.length; i < il; i ++ ) { + // flatten bone matrices to array - // compute the offset between the current and the original transform + for ( var i = 0, il = bones.length; i < il; i ++ ) { - var matrix = bones[ i ] ? bones[ i ].matrixWorld : identityMatrix; + // compute the offset between the current and the original transform - offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] ); - offsetMatrix.toArray( boneMatrices, i * 16 ); + var matrix = bones[ i ] ? bones[ i ].matrixWorld : _identityMatrix; - } + _offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] ); + _offsetMatrix.toArray( boneMatrices, i * 16 ); - if ( boneTexture !== undefined ) { + } - boneTexture.needsUpdate = true; + if ( boneTexture !== undefined ) { - } + boneTexture.needsUpdate = true; - }; + } - } )(), + }, clone: function () { @@ -26749,6 +26527,12 @@ * @author mrdoob / http://mrdoob.com/ */ + var _start = new Vector3(); + var _end = new Vector3(); + var _inverseMatrix$1 = new Matrix4(); + var _ray$1 = new Ray(); + var _sphere$2 = new Sphere(); + function Line( geometry, material, mode ) { if ( mode === 1 ) { @@ -26772,186 +26556,139 @@ isLine: true, - computeLineDistances: ( function () { - - var start = new Vector3(); - var end = new Vector3(); - - return function computeLineDistances() { - - var geometry = this.geometry; - - if ( geometry.isBufferGeometry ) { - - // we assume non-indexed geometry - - if ( geometry.index === null ) { - - var positionAttribute = geometry.attributes.position; - var lineDistances = [ 0 ]; - - for ( var i = 1, l = positionAttribute.count; i < l; i ++ ) { - - start.fromBufferAttribute( positionAttribute, i - 1 ); - end.fromBufferAttribute( positionAttribute, i ); - - lineDistances[ i ] = lineDistances[ i - 1 ]; - lineDistances[ i ] += start.distanceTo( end ); - - } - - geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); + computeLineDistances: function () { - } else { + var geometry = this.geometry; - console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); + if ( geometry.isBufferGeometry ) { - } + // we assume non-indexed geometry - } else if ( geometry.isGeometry ) { + if ( geometry.index === null ) { - var vertices = geometry.vertices; - var lineDistances = geometry.lineDistances; + var positionAttribute = geometry.attributes.position; + var lineDistances = [ 0 ]; - lineDistances[ 0 ] = 0; + for ( var i = 1, l = positionAttribute.count; i < l; i ++ ) { - for ( var i = 1, l = vertices.length; i < l; i ++ ) { + _start.fromBufferAttribute( positionAttribute, i - 1 ); + _end.fromBufferAttribute( positionAttribute, i ); lineDistances[ i ] = lineDistances[ i - 1 ]; - lineDistances[ i ] += vertices[ i - 1 ].distanceTo( vertices[ i ] ); + lineDistances[ i ] += _start.distanceTo( _end ); } - } + geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); - return this; - - }; - - }() ), - - raycast: ( function () { - - var inverseMatrix = new Matrix4(); - var ray = new Ray(); - var sphere = new Sphere(); - - return function raycast( raycaster, intersects ) { - - var precision = raycaster.linePrecision; + } else { - var geometry = this.geometry; - var matrixWorld = this.matrixWorld; + console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); - // Checking boundingSphere distance to ray + } - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + } else if ( geometry.isGeometry ) { - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); - sphere.radius += precision; + var vertices = geometry.vertices; + var lineDistances = geometry.lineDistances; - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + lineDistances[ 0 ] = 0; - // + for ( var i = 1, l = vertices.length; i < l; i ++ ) { - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + lineDistances[ i ] = lineDistances[ i - 1 ]; + lineDistances[ i ] += vertices[ i - 1 ].distanceTo( vertices[ i ] ); - var localPrecision = precision / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); - var localPrecisionSq = localPrecision * localPrecision; + } - var vStart = new Vector3(); - var vEnd = new Vector3(); - var interSegment = new Vector3(); - var interRay = new Vector3(); - var step = ( this && this.isLineSegments ) ? 2 : 1; + } - if ( geometry.isBufferGeometry ) { + return this; - var index = geometry.index; - var attributes = geometry.attributes; - var positions = attributes.position.array; + }, - if ( index !== null ) { + raycast: function ( raycaster, intersects ) { - var indices = index.array; + var precision = raycaster.linePrecision; - for ( var i = 0, l = indices.length - 1; i < l; i += step ) { + var geometry = this.geometry; + var matrixWorld = this.matrixWorld; - var a = indices[ i ]; - var b = indices[ i + 1 ]; + // Checking boundingSphere distance to ray - vStart.fromArray( positions, a * 3 ); - vEnd.fromArray( positions, b * 3 ); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); + _sphere$2.copy( geometry.boundingSphere ); + _sphere$2.applyMatrix4( matrixWorld ); + _sphere$2.radius += precision; - if ( distSq > localPrecisionSq ) continue; + if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) return; - interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + // - var distance = raycaster.ray.origin.distanceTo( interRay ); + _inverseMatrix$1.getInverse( matrixWorld ); + _ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 ); - if ( distance < raycaster.near || distance > raycaster.far ) continue; + var localPrecision = precision / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); + var localPrecisionSq = localPrecision * localPrecision; - intersects.push( { + var vStart = new Vector3(); + var vEnd = new Vector3(); + var interSegment = new Vector3(); + var interRay = new Vector3(); + var step = ( this && this.isLineSegments ) ? 2 : 1; - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4( this.matrixWorld ), - index: i, - face: null, - faceIndex: null, - object: this + if ( geometry.isBufferGeometry ) { - } ); + var index = geometry.index; + var attributes = geometry.attributes; + var positions = attributes.position.array; - } + if ( index !== null ) { - } else { + var indices = index.array; - for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) { + for ( var i = 0, l = indices.length - 1; i < l; i += step ) { - vStart.fromArray( positions, 3 * i ); - vEnd.fromArray( positions, 3 * i + 3 ); + var a = indices[ i ]; + var b = indices[ i + 1 ]; - var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); + vStart.fromArray( positions, a * 3 ); + vEnd.fromArray( positions, b * 3 ); - if ( distSq > localPrecisionSq ) continue; + var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); - interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + if ( distSq > localPrecisionSq ) continue; - var distance = raycaster.ray.origin.distanceTo( interRay ); + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation - if ( distance < raycaster.near || distance > raycaster.far ) continue; + var distance = raycaster.ray.origin.distanceTo( interRay ); - intersects.push( { + if ( distance < raycaster.near || distance > raycaster.far ) continue; - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4( this.matrixWorld ), - index: i, - face: null, - faceIndex: null, - object: this + intersects.push( { - } ); + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this - } + } ); } - } else if ( geometry.isGeometry ) { + } else { - var vertices = geometry.vertices; - var nbVertices = vertices.length; + for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) { - for ( var i = 0; i < nbVertices - 1; i += step ) { + vStart.fromArray( positions, 3 * i ); + vEnd.fromArray( positions, 3 * i + 3 ); - var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); + var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); if ( distSq > localPrecisionSq ) continue; @@ -26978,9 +26715,41 @@ } - }; + } else if ( geometry.isGeometry ) { + + var vertices = geometry.vertices; + var nbVertices = vertices.length; - }() ), + for ( var i = 0; i < nbVertices - 1; i += step ) { + + var distSq = _ray$1.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); + + if ( distSq > localPrecisionSq ) continue; + + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + + var distance = raycaster.ray.origin.distanceTo( interRay ); + + if ( distance < raycaster.near || distance > raycaster.far ) continue; + + intersects.push( { + + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this + + } ); + + } + + } + + }, clone: function () { @@ -26994,6 +26763,9 @@ * @author mrdoob / http://mrdoob.com/ */ + var _start$1 = new Vector3(); + var _end$1 = new Vector3(); + function LineSegments( geometry, material ) { Line.call( this, geometry, material ); @@ -27008,64 +26780,57 @@ isLineSegments: true, - computeLineDistances: ( function () { - - var start = new Vector3(); - var end = new Vector3(); - - return function computeLineDistances() { - - var geometry = this.geometry; + computeLineDistances: function () { - if ( geometry.isBufferGeometry ) { + var geometry = this.geometry; - // we assume non-indexed geometry + if ( geometry.isBufferGeometry ) { - if ( geometry.index === null ) { + // we assume non-indexed geometry - var positionAttribute = geometry.attributes.position; - var lineDistances = []; + if ( geometry.index === null ) { - for ( var i = 0, l = positionAttribute.count; i < l; i += 2 ) { + var positionAttribute = geometry.attributes.position; + var lineDistances = []; - start.fromBufferAttribute( positionAttribute, i ); - end.fromBufferAttribute( positionAttribute, i + 1 ); + for ( var i = 0, l = positionAttribute.count; i < l; i += 2 ) { - lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; - lineDistances[ i + 1 ] = lineDistances[ i ] + start.distanceTo( end ); + _start$1.fromBufferAttribute( positionAttribute, i ); + _end$1.fromBufferAttribute( positionAttribute, i + 1 ); - } + lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; + lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 ); - geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); + } - } else { + geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); - console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); + } else { - } + console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); - } else if ( geometry.isGeometry ) { + } - var vertices = geometry.vertices; - var lineDistances = geometry.lineDistances; + } else if ( geometry.isGeometry ) { - for ( var i = 0, l = vertices.length; i < l; i += 2 ) { + var vertices = geometry.vertices; + var lineDistances = geometry.lineDistances; - start.copy( vertices[ i ] ); - end.copy( vertices[ i + 1 ] ); + for ( var i = 0, l = vertices.length; i < l; i += 2 ) { - lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; - lineDistances[ i + 1 ] = lineDistances[ i ] + start.distanceTo( end ); + _start$1.copy( vertices[ i ] ); + _end$1.copy( vertices[ i + 1 ] ); - } + lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; + lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 ); } - return this; + } - }; + return this; - }() ) + } } ); @@ -27152,6 +26917,11 @@ * @author alteredq / http://alteredqualia.com/ */ + var _inverseMatrix$2 = new Matrix4(); + var _ray$2 = new Ray(); + var _sphere$3 = new Sphere(); + var _position$1 = new Vector3(); + function Points( geometry, material ) { Object3D.call( this ); @@ -27171,114 +26941,75 @@ isPoints: true, - raycast: ( function () { + raycast: function ( raycaster, intersects ) { - var inverseMatrix = new Matrix4(); - var ray = new Ray(); - var sphere = new Sphere(); - - return function raycast( raycaster, intersects ) { - - var object = this; - var geometry = this.geometry; - var matrixWorld = this.matrixWorld; - var threshold = raycaster.params.Points.threshold; + var geometry = this.geometry; + var matrixWorld = this.matrixWorld; + var threshold = raycaster.params.Points.threshold; - // Checking boundingSphere distance to ray + // Checking boundingSphere distance to ray - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); - sphere.radius += threshold; + _sphere$3.copy( geometry.boundingSphere ); + _sphere$3.applyMatrix4( matrixWorld ); + _sphere$3.radius += threshold; - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return; - // - - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + // - var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); - var localThresholdSq = localThreshold * localThreshold; - var position = new Vector3(); - var intersectPoint = new Vector3(); + _inverseMatrix$2.getInverse( matrixWorld ); + _ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 ); - function testPoint( point, index ) { + var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); + var localThresholdSq = localThreshold * localThreshold; - var rayPointDistanceSq = ray.distanceSqToPoint( point ); + if ( geometry.isBufferGeometry ) { - if ( rayPointDistanceSq < localThresholdSq ) { + var index = geometry.index; + var attributes = geometry.attributes; + var positions = attributes.position.array; - ray.closestPointToPoint( point, intersectPoint ); - intersectPoint.applyMatrix4( matrixWorld ); + if ( index !== null ) { - var distance = raycaster.ray.origin.distanceTo( intersectPoint ); + var indices = index.array; - if ( distance < raycaster.near || distance > raycaster.far ) return; + for ( var i = 0, il = indices.length; i < il; i ++ ) { - intersects.push( { + var a = indices[ i ]; - distance: distance, - distanceToRay: Math.sqrt( rayPointDistanceSq ), - point: intersectPoint.clone(), - index: index, - face: null, - object: object + _position$1.fromArray( positions, a * 3 ); - } ); + testPoint( _position$1, a, localThresholdSq, matrixWorld, raycaster, intersects, this ); } - } - - if ( geometry.isBufferGeometry ) { - - var index = geometry.index; - var attributes = geometry.attributes; - var positions = attributes.position.array; - - if ( index !== null ) { - - var indices = index.array; - - for ( var i = 0, il = indices.length; i < il; i ++ ) { - - var a = indices[ i ]; - - position.fromArray( positions, a * 3 ); - - testPoint( position, a ); - - } - - } else { - - for ( var i = 0, l = positions.length / 3; i < l; i ++ ) { + } else { - position.fromArray( positions, i * 3 ); + for ( var i = 0, l = positions.length / 3; i < l; i ++ ) { - testPoint( position, i ); + _position$1.fromArray( positions, i * 3 ); - } + testPoint( _position$1, i, localThresholdSq, matrixWorld, raycaster, intersects, this ); } - } else { + } - var vertices = geometry.vertices; + } else { - for ( var i = 0, l = vertices.length; i < l; i ++ ) { + var vertices = geometry.vertices; - testPoint( vertices[ i ], i ); + for ( var i = 0, l = vertices.length; i < l; i ++ ) { - } + testPoint( vertices[ i ], i, localThresholdSq, matrixWorld, raycaster, intersects, this ); } - }; + } - }() ), + }, updateMorphTargets: function () { @@ -27334,6 +27065,36 @@ } ); + function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) { + + var rayPointDistanceSq = _ray$2.distanceSqToPoint( point ); + + if ( rayPointDistanceSq < localThresholdSq ) { + + var intersectPoint = new Vector3(); + + _ray$2.closestPointToPoint( point, intersectPoint ); + intersectPoint.applyMatrix4( matrixWorld ); + + var distance = raycaster.ray.origin.distanceTo( intersectPoint ); + + if ( distance < raycaster.near || distance > raycaster.far ) return; + + intersects.push( { + + distance: distance, + distanceToRay: Math.sqrt( rayPointDistanceSq ), + point: intersectPoint, + index: index, + face: null, + object: object + + } ); + + } + + } + /** * @author mrdoob / http://mrdoob.com/ */ @@ -32210,8 +31971,13 @@ * * parameters = { * reflectivity: - * clearCoat: - * clearCoatRoughness: + * clearcoat: + * clearcoatRoughness: + * + * sheen: + * + * clearcoatNormalScale: , + * clearcoatNormalMap: new THREE.Texture( ), * } */ @@ -32219,14 +31985,26 @@ MeshStandardMaterial.call( this ); - this.defines = { 'PHYSICAL': '' }; + this.defines = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; this.type = 'MeshPhysicalMaterial'; this.reflectivity = 0.5; // maps to F0 = 0.04 - this.clearCoat = 0.0; - this.clearCoatRoughness = 0.0; + this.clearcoat = 0.0; + this.clearcoatRoughness = 0.0; + + this.sheen = null; // null will disable sheen bsdf + + this.clearcoatNormalScale = new Vector2( 1, 1 ); + this.clearcoatNormalMap = null; + + this.transparency = 0.0; this.setValues( parameters ); @@ -32241,12 +32019,25 @@ MeshStandardMaterial.prototype.copy.call( this, source ); - this.defines = { 'PHYSICAL': '' }; + this.defines = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; this.reflectivity = source.reflectivity; - this.clearCoat = source.clearCoat; - this.clearCoatRoughness = source.clearCoatRoughness; + this.clearcoat = source.clearcoat; + this.clearcoatRoughness = source.clearcoatRoughness; + + if ( source.sheen ) this.sheen = ( this.sheen || new Color() ).copy( source.sheen ); + else this.sheen = null; + + this.clearcoatNormalMap = source.clearcoatNormalMap; + this.clearcoatNormalScale.copy( source.clearcoatNormalScale ); + + this.transparency = source.transparency; return this; @@ -34756,6 +34547,84 @@ var DefaultLoadingManager = new LoadingManager(); + /** + * @author alteredq / http://alteredqualia.com/ + */ + + function Loader( manager ) { + + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + + this.crossOrigin = 'anonymous'; + this.path = ''; + this.resourcePath = ''; + + } + + Object.assign( Loader.prototype, { + + load: function ( /* url, onLoad, onProgress, onError */ ) {}, + + parse: function ( /* data */ ) {}, + + setCrossOrigin: function ( crossOrigin ) { + + this.crossOrigin = crossOrigin; + return this; + + }, + + setPath: function ( path ) { + + this.path = path; + return this; + + }, + + setResourcePath: function ( resourcePath ) { + + this.resourcePath = resourcePath; + return this; + + } + + } ); + + // + + Loader.Handlers = { + + handlers: [], + + add: function ( regex, loader ) { + + this.handlers.push( regex, loader ); + + }, + + get: function ( file ) { + + var handlers = this.handlers; + + for ( var i = 0, l = handlers.length; i < l; i += 2 ) { + + var regex = handlers[ i ]; + var loader = handlers[ i + 1 ]; + + if ( regex.test( file ) ) { + + return loader; + + } + + } + + return null; + + } + + }; + /** * @author mrdoob / http://mrdoob.com/ */ @@ -34764,11 +34633,13 @@ function FileLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( FileLoader.prototype, { + FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: FileLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -35033,13 +34904,6 @@ }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - setResponseType: function ( value ) { this.responseType = value; @@ -35076,11 +34940,13 @@ function AnimationLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( AnimationLoader.prototype, { + AnimationLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: AnimationLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -35110,13 +34976,6 @@ return animations; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35129,14 +34988,16 @@ function CompressedTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); // override in sub classes this._parser = null; } - Object.assign( CompressedTextureLoader.prototype, { + CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: CompressedTextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -35244,13 +35105,6 @@ return texture; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35263,14 +35117,16 @@ function DataTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); // override in sub classes this._parser = null; } - Object.assign( DataTextureLoader.prototype, { + DataTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: DataTextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -35339,13 +35195,6 @@ return texture; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35354,21 +35203,18 @@ * @author mrdoob / http://mrdoob.com/ */ - function ImageLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( ImageLoader.prototype, { + ImageLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: ImageLoader, load: function ( url, onLoad, onProgress, onError ) { - if ( url === undefined ) url = ''; - if ( this.path !== undefined ) url = this.path + url; url = this.manager.resolveURL( url ); @@ -35435,20 +35281,6 @@ return image; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35460,13 +35292,13 @@ function CubeTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( CubeTextureLoader.prototype, { + CubeTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: CubeTextureLoader, load: function ( urls, onLoad, onProgress, onError ) { @@ -35506,20 +35338,6 @@ return texture; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35528,16 +35346,15 @@ * @author mrdoob / http://mrdoob.com/ */ - function TextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( TextureLoader.prototype, { + TextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: TextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -35567,20 +35384,6 @@ return texture; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -37694,12 +37497,84 @@ this.mapSize = new Vector2( 512, 512 ); this.map = null; + this.mapPass = null; this.matrix = new Matrix4(); + this._frustum = new Frustum(); + this._frameExtents = new Vector2( 1, 1 ); + + this._viewportCount = 1; + + this._viewports = [ + + new Vector4( 0, 0, 1, 1 ) + + ]; + } Object.assign( LightShadow.prototype, { + _projScreenMatrix: new Matrix4(), + + _lightPositionWorld: new Vector3(), + + _lookTarget: new Vector3(), + + getViewportCount: function () { + + return this._viewportCount; + + }, + + getFrustum: function () { + + return this._frustum; + + }, + + updateMatrices: function ( light ) { + + var shadowCamera = this.camera, + shadowMatrix = this.matrix, + projScreenMatrix = this._projScreenMatrix, + lookTarget = this._lookTarget, + lightPositionWorld = this._lightPositionWorld; + + lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + shadowCamera.position.copy( lightPositionWorld ); + + lookTarget.setFromMatrixPosition( light.target.matrixWorld ); + shadowCamera.lookAt( lookTarget ); + shadowCamera.updateMatrixWorld(); + + projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); + this._frustum.setFromMatrix( projScreenMatrix ); + + shadowMatrix.set( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0 + ); + + shadowMatrix.multiply( shadowCamera.projectionMatrix ); + shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + + }, + + getViewport: function ( viewportIndex ) { + + return this._viewports[ viewportIndex ]; + + }, + + getFrameExtents: function () { + + return this._frameExtents; + + }, + copy: function ( source ) { this.camera = source.camera.clone(); @@ -37752,7 +37627,7 @@ isSpotLightShadow: true, - update: function ( light ) { + updateMatrices: function ( light, viewCamera, viewportIndex ) { var camera = this.camera; @@ -37769,6 +37644,8 @@ } + LightShadow.prototype.updateMatrices.call( this, light, viewCamera, viewportIndex ); + } } ); @@ -37839,6 +37716,86 @@ } ); + function PointLightShadow() { + + LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) ); + + this._frameExtents = new Vector2( 4, 2 ); + + this._viewportCount = 6; + + this._viewports = [ + // These viewports map a cube-map onto a 2D texture with the + // following orientation: + // + // xzXZ + // y Y + // + // X - Positive x direction + // x - Negative x direction + // Y - Positive y direction + // y - Negative y direction + // Z - Positive z direction + // z - Negative z direction + + // positive X + new Vector4( 2, 1, 1, 1 ), + // negative X + new Vector4( 0, 1, 1, 1 ), + // positive Z + new Vector4( 3, 1, 1, 1 ), + // negative Z + new Vector4( 1, 1, 1, 1 ), + // positive Y + new Vector4( 3, 0, 1, 1 ), + // negative Y + new Vector4( 1, 0, 1, 1 ) + ]; + + this._cubeDirections = [ + new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), + new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) + ]; + + this._cubeUps = [ + new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), + new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) + ]; + + } + + PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { + + constructor: PointLightShadow, + + isPointLightShadow: true, + + updateMatrices: function ( light, viewCamera, viewportIndex ) { + + var camera = this.camera, + shadowMatrix = this.matrix, + lightPositionWorld = this._lightPositionWorld, + lookTarget = this._lookTarget, + projScreenMatrix = this._projScreenMatrix; + + lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + camera.position.copy( lightPositionWorld ); + + lookTarget.copy( camera.position ); + lookTarget.add( this._cubeDirections[ viewportIndex ] ); + camera.up.copy( this._cubeUps[ viewportIndex ] ); + camera.lookAt( lookTarget ); + camera.updateMatrixWorld(); + + shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z ); + + projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + this._frustum.setFromMatrix( projScreenMatrix ); + + } + + } ); + /** * @author mrdoob / http://mrdoob.com/ */ @@ -37870,7 +37827,7 @@ this.distance = ( distance !== undefined ) ? distance : 0; this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. - this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) ); + this.shadow = new PointLightShadow(); } @@ -38041,7 +37998,7 @@ * @author mrdoob / http://mrdoob.com/ */ - function DirectionalLightShadow( ) { + function DirectionalLightShadow() { LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); @@ -38049,7 +38006,15 @@ DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { - constructor: DirectionalLightShadow + constructor: DirectionalLightShadow, + + isDirectionalLightShadow: true, + + updateMatrices: function ( light, viewCamera, viewportIndex ) { + + LightShadow.prototype.updateMatrices.call( this, light, viewCamera, viewportIndex ); + + } } ); @@ -38166,12 +38131,15 @@ function MaterialLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); + this.textures = {}; } - Object.assign( MaterialLoader.prototype, { + MaterialLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: MaterialLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -38213,8 +38181,8 @@ if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive ); if ( json.specular !== undefined ) material.specular.setHex( json.specular ); if ( json.shininess !== undefined ) material.shininess = json.shininess; - if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat; - if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness; + if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat; + if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness; if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors; if ( json.fog !== undefined ) material.fog = json.fog; if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; @@ -38249,6 +38217,9 @@ if ( json.dithering !== undefined ) material.dithering = json.dithering; if ( json.visible !== undefined ) material.visible = json.visible; + + if ( json.toneMapped !== undefined ) material.toneMapped = json.toneMapped; + if ( json.userData !== undefined ) material.userData = json.userData; // Shader Material @@ -38381,14 +38352,10 @@ if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); - return material; - - }, - - setPath: function ( value ) { + if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap ); + if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale ); - this.path = value; - return this; + return material; }, @@ -38560,11 +38527,13 @@ function BufferGeometryLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( BufferGeometryLoader.prototype, { + BufferGeometryLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: BufferGeometryLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -38668,13 +38637,6 @@ return geometry; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -38698,20 +38660,19 @@ function ObjectLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - this.resourcePath = ''; + Loader.call( this, manager ); } - Object.assign( ObjectLoader.prototype, { + ObjectLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: ObjectLoader, load: function ( url, onLoad, onProgress, onError ) { var scope = this; - var path = ( this.path === undefined ) ? LoaderUtils.extractUrlBase( url ) : this.path; + var path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path; this.resourcePath = this.resourcePath || path; var loader = new FileLoader( scope.manager ); @@ -38749,27 +38710,6 @@ }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - parse: function ( json, onLoad ) { var shapes = this.parseShape( json.shapes ); @@ -39677,12 +39617,13 @@ } - this.manager = manager !== undefined ? manager : DefaultLoadingManager; + Loader.call( this, manager ); + this.options = undefined; } - ImageBitmapLoader.prototype = { + ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ), { constructor: ImageBitmapLoader, @@ -39758,22 +39699,9 @@ scope.manager.itemStart( url ); - }, - - setCrossOrigin: function ( /* value */ ) { - - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } - }; + } ); /** * @author zz85 / http://www.lab4games.net/zz85/blog @@ -40208,11 +40136,13 @@ function FontLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( FontLoader.prototype, { + FontLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: FontLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -40247,359 +40177,33 @@ return new Font( json ); - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); - /** - * @author alteredq / http://alteredqualia.com/ - */ - - function Loader() {} - - Loader.Handlers = { - - handlers: [], - - add: function ( regex, loader ) { - - this.handlers.push( regex, loader ); - - }, - - get: function ( file ) { - - var handlers = this.handlers; - - for ( var i = 0, l = handlers.length; i < l; i += 2 ) { - - var regex = handlers[ i ]; - var loader = handlers[ i + 1 ]; - - if ( regex.test( file ) ) { - - return loader; - - } - - } - - return null; - - } - - }; - - Object.assign( Loader.prototype, { - - crossOrigin: 'anonymous', - - onLoadStart: function () {}, - - onLoadProgress: function () {}, - - onLoadComplete: function () {}, - - initMaterials: function ( materials, texturePath, crossOrigin ) { - - var array = []; - - for ( var i = 0; i < materials.length; ++ i ) { - - array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin ); - - } - - return array; - - }, - - createMaterial: ( function () { - - var BlendingMode = { - NoBlending: NoBlending, - NormalBlending: NormalBlending, - AdditiveBlending: AdditiveBlending, - SubtractiveBlending: SubtractiveBlending, - MultiplyBlending: MultiplyBlending, - CustomBlending: CustomBlending - }; - - var color = new Color(); - var textureLoader = new TextureLoader(); - var materialLoader = new MaterialLoader(); - - return function createMaterial( m, texturePath, crossOrigin ) { - - // convert from old material format - - var textures = {}; - - function loadTexture( path, repeat, offset, wrap, anisotropy ) { - - var fullPath = texturePath + path; - var loader = Loader.Handlers.get( fullPath ); - - var texture; - - if ( loader !== null ) { - - texture = loader.load( fullPath ); - - } else { - - textureLoader.setCrossOrigin( crossOrigin ); - texture = textureLoader.load( fullPath ); - - } - - if ( repeat !== undefined ) { - - texture.repeat.fromArray( repeat ); - - if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping; - if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping; - - } - - if ( offset !== undefined ) { - - texture.offset.fromArray( offset ); - - } - - if ( wrap !== undefined ) { - - if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping; - if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping; - - if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping; - if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping; - - } - - if ( anisotropy !== undefined ) { - - texture.anisotropy = anisotropy; - - } - - var uuid = _Math.generateUUID(); - - textures[ uuid ] = texture; - - return uuid; - - } - - // - - var json = { - uuid: _Math.generateUUID(), - type: 'MeshLambertMaterial' - }; - - for ( var name in m ) { - - var value = m[ name ]; - - switch ( name ) { - - case 'DbgColor': - case 'DbgIndex': - case 'opticalDensity': - case 'illumination': - break; - case 'DbgName': - json.name = value; - break; - case 'blending': - json.blending = BlendingMode[ value ]; - break; - case 'colorAmbient': - case 'mapAmbient': - console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' ); - break; - case 'colorDiffuse': - json.color = color.fromArray( value ).getHex(); - break; - case 'colorSpecular': - json.specular = color.fromArray( value ).getHex(); - break; - case 'colorEmissive': - json.emissive = color.fromArray( value ).getHex(); - break; - case 'specularCoef': - json.shininess = value; - break; - case 'shading': - if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial'; - if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial'; - if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial'; - break; - case 'mapDiffuse': - json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy ); - break; - case 'mapDiffuseRepeat': - case 'mapDiffuseOffset': - case 'mapDiffuseWrap': - case 'mapDiffuseAnisotropy': - break; - case 'mapEmissive': - json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy ); - break; - case 'mapEmissiveRepeat': - case 'mapEmissiveOffset': - case 'mapEmissiveWrap': - case 'mapEmissiveAnisotropy': - break; - case 'mapLight': - json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy ); - break; - case 'mapLightRepeat': - case 'mapLightOffset': - case 'mapLightWrap': - case 'mapLightAnisotropy': - break; - case 'mapAO': - json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy ); - break; - case 'mapAORepeat': - case 'mapAOOffset': - case 'mapAOWrap': - case 'mapAOAnisotropy': - break; - case 'mapBump': - json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy ); - break; - case 'mapBumpScale': - json.bumpScale = value; - break; - case 'mapBumpRepeat': - case 'mapBumpOffset': - case 'mapBumpWrap': - case 'mapBumpAnisotropy': - break; - case 'mapNormal': - json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy ); - break; - case 'mapNormalFactor': - json.normalScale = value; - break; - case 'mapNormalRepeat': - case 'mapNormalOffset': - case 'mapNormalWrap': - case 'mapNormalAnisotropy': - break; - case 'mapSpecular': - json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy ); - break; - case 'mapSpecularRepeat': - case 'mapSpecularOffset': - case 'mapSpecularWrap': - case 'mapSpecularAnisotropy': - break; - case 'mapMetalness': - json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy ); - break; - case 'mapMetalnessRepeat': - case 'mapMetalnessOffset': - case 'mapMetalnessWrap': - case 'mapMetalnessAnisotropy': - break; - case 'mapRoughness': - json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy ); - break; - case 'mapRoughnessRepeat': - case 'mapRoughnessOffset': - case 'mapRoughnessWrap': - case 'mapRoughnessAnisotropy': - break; - case 'mapAlpha': - json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy ); - break; - case 'mapAlphaRepeat': - case 'mapAlphaOffset': - case 'mapAlphaWrap': - case 'mapAlphaAnisotropy': - break; - case 'flipSided': - json.side = BackSide; - break; - case 'doubleSided': - json.side = DoubleSide; - break; - case 'transparency': - console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' ); - json.opacity = value; - break; - case 'depthTest': - case 'depthWrite': - case 'colorWrite': - case 'opacity': - case 'reflectivity': - case 'transparent': - case 'visible': - case 'wireframe': - json[ name ] = value; - break; - case 'vertexColors': - if ( value === true ) json.vertexColors = VertexColors; - if ( value === 'face' ) json.vertexColors = FaceColors; - break; - default: - console.error( 'THREE.Loader.createMaterial: Unsupported', name, value ); - break; - - } - - } - - if ( json.type === 'MeshBasicMaterial' ) delete json.emissive; - if ( json.type !== 'MeshPhongMaterial' ) delete json.specular; - - if ( json.opacity < 1 ) json.transparent = true; - - materialLoader.setTextures( textures ); - - return materialLoader.parse( json ); - - }; - - } )() - - } ); - /** * @author mrdoob / http://mrdoob.com/ */ - var context; + var _context; var AudioContext = { getContext: function () { - if ( context === undefined ) { + if ( _context === undefined ) { - context = new ( window.AudioContext || window.webkitAudioContext )(); + _context = new ( window.AudioContext || window.webkitAudioContext )(); } - return context; + return _context; }, setContext: function ( value ) { - context = value; + _context = value; } @@ -40611,11 +40215,13 @@ function AudioLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( AudioLoader.prototype, { + AudioLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: AudioLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -40637,13 +40243,6 @@ }, onProgress, onError ); - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -40825,13 +40424,15 @@ }, - fromArray: function ( array ) { + fromArray: function ( array, offset ) { + + if ( offset === undefined ) offset = 0; var coefficients = this.coefficients; for ( var i = 0; i < 9; i ++ ) { - coefficients[ i ].fromArray( array, i * 3 ); + coefficients[ i ].fromArray( array, offset + ( i * 3 ) ); } @@ -40839,14 +40440,16 @@ }, - toArray: function () { + toArray: function ( array, offset ) { + + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - var array = []; var coefficients = this.coefficients; for ( var i = 0; i < 9; i ++ ) { - coefficients[ i ].toArray( array, i * 3 ); + coefficients[ i ].toArray( array, offset + ( i * 3 ) ); } @@ -41018,6 +40621,9 @@ } ); + var _eyeRight = new Matrix4(); + var _eyeLeft = new Matrix4(); + /** * @author mrdoob / http://mrdoob.com/ */ @@ -41038,75 +40644,78 @@ this.cameraR.layers.enable( 2 ); this.cameraR.matrixAutoUpdate = false; + this._cache = { + focus: null, + fov: null, + aspect: null, + near: null, + far: null, + zoom: null, + eyeSep: null + }; + } Object.assign( StereoCamera.prototype, { - update: ( function () { + update: function ( camera ) { - var instance, focus, fov, aspect, near, far, zoom, eyeSep; + var cache = this._cache; - var eyeRight = new Matrix4(); - var eyeLeft = new Matrix4(); + var needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov || + cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near || + cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep; - return function update( camera ) { + if ( needsUpdate ) { - var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov || - aspect !== camera.aspect * this.aspect || near !== camera.near || - far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep; + cache.focus = camera.focus; + cache.fov = camera.fov; + cache.aspect = camera.aspect * this.aspect; + cache.near = camera.near; + cache.far = camera.far; + cache.zoom = camera.zoom; + cache.eyeSep = this.eyeSep; - if ( needsUpdate ) { + // Off-axis stereoscopic effect based on + // http://paulbourke.net/stereographics/stereorender/ - instance = this; - focus = camera.focus; - fov = camera.fov; - aspect = camera.aspect * this.aspect; - near = camera.near; - far = camera.far; - zoom = camera.zoom; + var projectionMatrix = camera.projectionMatrix.clone(); + var eyeSepHalf = cache.eyeSep / 2; + var eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus; + var ymax = ( cache.near * Math.tan( _Math.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom; + var xmin, xmax; - // Off-axis stereoscopic effect based on - // http://paulbourke.net/stereographics/stereorender/ + // translate xOffset - var projectionMatrix = camera.projectionMatrix.clone(); - eyeSep = this.eyeSep / 2; - var eyeSepOnProjection = eyeSep * near / focus; - var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom; - var xmin, xmax; + _eyeLeft.elements[ 12 ] = - eyeSepHalf; + _eyeRight.elements[ 12 ] = eyeSepHalf; - // translate xOffset + // for left eye - eyeLeft.elements[ 12 ] = - eyeSep; - eyeRight.elements[ 12 ] = eyeSep; + xmin = - ymax * cache.aspect + eyeSepOnProjection; + xmax = ymax * cache.aspect + eyeSepOnProjection; - // for left eye + projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin ); + projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); - xmin = - ymax * aspect + eyeSepOnProjection; - xmax = ymax * aspect + eyeSepOnProjection; + this.cameraL.projectionMatrix.copy( projectionMatrix ); - projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin ); - projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); + // for right eye - this.cameraL.projectionMatrix.copy( projectionMatrix ); + xmin = - ymax * cache.aspect - eyeSepOnProjection; + xmax = ymax * cache.aspect - eyeSepOnProjection; - // for right eye + projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin ); + projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); - xmin = - ymax * aspect - eyeSepOnProjection; - xmax = ymax * aspect - eyeSepOnProjection; + this.cameraR.projectionMatrix.copy( projectionMatrix ); - projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin ); - projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); - - this.cameraR.projectionMatrix.copy( projectionMatrix ); - - } - - this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft ); - this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight ); + } - }; + this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft ); + this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight ); - } )() + } } ); @@ -41185,6 +40794,11 @@ * @author mrdoob / http://mrdoob.com/ */ + var _position$2 = new Vector3(); + var _quaternion$3 = new Quaternion(); + var _scale$1 = new Vector3(); + var _orientation = new Vector3(); + function AudioListener() { Object3D.call( this ); @@ -41200,6 +40814,10 @@ this.timeDelta = 0; + // private + + this._clock = new Clock(); + } AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), { @@ -41268,54 +40886,43 @@ }, - updateMatrixWorld: ( function () { - - var position = new Vector3(); - var quaternion = new Quaternion(); - var scale = new Vector3(); - - var orientation = new Vector3(); - var clock = new Clock(); - - return function updateMatrixWorld( force ) { + updateMatrixWorld: function ( force ) { - Object3D.prototype.updateMatrixWorld.call( this, force ); + Object3D.prototype.updateMatrixWorld.call( this, force ); - var listener = this.context.listener; - var up = this.up; + var listener = this.context.listener; + var up = this.up; - this.timeDelta = clock.getDelta(); + this.timeDelta = this._clock.getDelta(); - this.matrixWorld.decompose( position, quaternion, scale ); + this.matrixWorld.decompose( _position$2, _quaternion$3, _scale$1 ); - orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion ); + _orientation.set( 0, 0, - 1 ).applyQuaternion( _quaternion$3 ); - if ( listener.positionX ) { + if ( listener.positionX ) { - // code path for Chrome (see #14393) + // code path for Chrome (see #14393) - var endTime = this.context.currentTime + this.timeDelta; + var endTime = this.context.currentTime + this.timeDelta; - listener.positionX.linearRampToValueAtTime( position.x, endTime ); - listener.positionY.linearRampToValueAtTime( position.y, endTime ); - listener.positionZ.linearRampToValueAtTime( position.z, endTime ); - listener.forwardX.linearRampToValueAtTime( orientation.x, endTime ); - listener.forwardY.linearRampToValueAtTime( orientation.y, endTime ); - listener.forwardZ.linearRampToValueAtTime( orientation.z, endTime ); - listener.upX.linearRampToValueAtTime( up.x, endTime ); - listener.upY.linearRampToValueAtTime( up.y, endTime ); - listener.upZ.linearRampToValueAtTime( up.z, endTime ); + listener.positionX.linearRampToValueAtTime( _position$2.x, endTime ); + listener.positionY.linearRampToValueAtTime( _position$2.y, endTime ); + listener.positionZ.linearRampToValueAtTime( _position$2.z, endTime ); + listener.forwardX.linearRampToValueAtTime( _orientation.x, endTime ); + listener.forwardY.linearRampToValueAtTime( _orientation.y, endTime ); + listener.forwardZ.linearRampToValueAtTime( _orientation.z, endTime ); + listener.upX.linearRampToValueAtTime( up.x, endTime ); + listener.upY.linearRampToValueAtTime( up.y, endTime ); + listener.upZ.linearRampToValueAtTime( up.z, endTime ); - } else { - - listener.setPosition( position.x, position.y, position.z ); - listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z ); + } else { - } + listener.setPosition( _position$2.x, _position$2.y, _position$2.z ); + listener.setOrientation( _orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z ); - }; + } - } )() + } } ); @@ -41343,6 +40950,7 @@ this.loop = false; this.startTime = 0; this.offset = 0; + this.duration = undefined; this.playbackRate = 1; this.isPlaying = false; this.hasPlaybackControl = true; @@ -41417,7 +41025,7 @@ source.loop = this.loop; source.onended = this.onEnded.bind( this ); this.startTime = this.context.currentTime; - source.start( this.startTime, this.offset ); + source.start( this.startTime, this.offset, this.duration ); this.isPlaying = true; @@ -41665,6 +41273,11 @@ * @author mrdoob / http://mrdoob.com/ */ + var _position$3 = new Vector3(); + var _quaternion$4 = new Quaternion(); + var _scale$2 = new Vector3(); + var _orientation$1 = new Vector3(); + function PositionalAudio( listener ) { Audio.call( this, listener ); @@ -41751,50 +41364,39 @@ }, - updateMatrixWorld: ( function () { - - var position = new Vector3(); - var quaternion = new Quaternion(); - var scale = new Vector3(); - - var orientation = new Vector3(); - - return function updateMatrixWorld( force ) { - - Object3D.prototype.updateMatrixWorld.call( this, force ); - - if ( this.hasPlaybackControl === true && this.isPlaying === false ) return; + updateMatrixWorld: function ( force ) { - this.matrixWorld.decompose( position, quaternion, scale ); + Object3D.prototype.updateMatrixWorld.call( this, force ); - orientation.set( 0, 0, 1 ).applyQuaternion( quaternion ); + if ( this.hasPlaybackControl === true && this.isPlaying === false ) return; - var panner = this.panner; + this.matrixWorld.decompose( _position$3, _quaternion$4, _scale$2 ); - if ( panner.positionX ) { + _orientation$1.set( 0, 0, 1 ).applyQuaternion( _quaternion$4 ); - // code path for Chrome and Firefox (see #14393) + var panner = this.panner; - var endTime = this.context.currentTime + this.listener.timeDelta; + if ( panner.positionX ) { - panner.positionX.linearRampToValueAtTime( position.x, endTime ); - panner.positionY.linearRampToValueAtTime( position.y, endTime ); - panner.positionZ.linearRampToValueAtTime( position.z, endTime ); - panner.orientationX.linearRampToValueAtTime( orientation.x, endTime ); - panner.orientationY.linearRampToValueAtTime( orientation.y, endTime ); - panner.orientationZ.linearRampToValueAtTime( orientation.z, endTime ); + // code path for Chrome and Firefox (see #14393) - } else { + var endTime = this.context.currentTime + this.listener.timeDelta; - panner.setPosition( position.x, position.y, position.z ); - panner.setOrientation( orientation.x, orientation.y, orientation.z ); + panner.positionX.linearRampToValueAtTime( _position$3.x, endTime ); + panner.positionY.linearRampToValueAtTime( _position$3.y, endTime ); + panner.positionZ.linearRampToValueAtTime( _position$3.z, endTime ); + panner.orientationX.linearRampToValueAtTime( _orientation$1.x, endTime ); + panner.orientationY.linearRampToValueAtTime( _orientation$1.y, endTime ); + panner.orientationZ.linearRampToValueAtTime( _orientation$1.z, endTime ); - } + } else { - }; + panner.setPosition( _position$3.x, _position$3.y, _position$3.z ); + panner.setOrientation( _orientation$1.x, _orientation$1.y, _orientation$1.z ); - } )() + } + } } ); @@ -42055,7 +41657,40 @@ */ // Characters [].:/ are reserved for track binding syntax. - var RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; + var _RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; + var _reservedRe = new RegExp( '[' + _RESERVED_CHARS_RE + ']', 'g' ); + + // Attempts to allow node names from any language. ES5's `\w` regexp matches + // only latin characters, and the unicode \p{L} is not yet supported. So + // instead, we exclude reserved characters and match everything else. + var _wordChar = '[^' + _RESERVED_CHARS_RE + ']'; + var _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\.', '' ) + ']'; + + // Parent directories, delimited by '/' or ':'. Currently unused, but must + // be matched to parse the rest of the track name. + var _directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', _wordChar ); + + // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. + var _nodeRe = /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot ); + + // Object on target node, and accessor. May not contain reserved + // characters. Accessor may contain any character except closing bracket. + var _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', _wordChar ); + + // Property and accessor. May not contain reserved characters. Accessor may + // contain any non-bracket characters. + var _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', _wordChar ); + + var _trackRe = new RegExp( '' + + '^' + + _directoryRe + + _nodeRe + + _objectRe + + _propertyRe + + '$' + ); + + var _supportedObjectNames = [ 'material', 'materials', 'bones' ]; function Composite( targetGroup, path, optionalParsedPath ) { @@ -42155,101 +41790,59 @@ * @param {string} name Node name to be sanitized. * @return {string} */ - sanitizeNodeName: ( function () { - - var reservedRe = new RegExp( '[' + RESERVED_CHARS_RE + ']', 'g' ); - - return function sanitizeNodeName( name ) { - - return name.replace( /\s/g, '_' ).replace( reservedRe, '' ); - - }; + sanitizeNodeName: function ( name ) { - }() ), + return name.replace( /\s/g, '_' ).replace( _reservedRe, '' ); - parseTrackName: function () { - - // Attempts to allow node names from any language. ES5's `\w` regexp matches - // only latin characters, and the unicode \p{L} is not yet supported. So - // instead, we exclude reserved characters and match everything else. - var wordChar = '[^' + RESERVED_CHARS_RE + ']'; - var wordCharOrDot = '[^' + RESERVED_CHARS_RE.replace( '\\.', '' ) + ']'; - - // Parent directories, delimited by '/' or ':'. Currently unused, but must - // be matched to parse the rest of the track name. - var directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', wordChar ); - - // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. - var nodeRe = /(WCOD+)?/.source.replace( 'WCOD', wordCharOrDot ); - - // Object on target node, and accessor. May not contain reserved - // characters. Accessor may contain any character except closing bracket. - var objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', wordChar ); - - // Property and accessor. May not contain reserved characters. Accessor may - // contain any non-bracket characters. - var propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', wordChar ); - - var trackRe = new RegExp( '' - + '^' - + directoryRe - + nodeRe - + objectRe - + propertyRe - + '$' - ); - - var supportedObjectNames = [ 'material', 'materials', 'bones' ]; - - return function parseTrackName( trackName ) { + }, - var matches = trackRe.exec( trackName ); + parseTrackName: function ( trackName ) { - if ( ! matches ) { + var matches = _trackRe.exec( trackName ); - throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName ); + if ( ! matches ) { - } + throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName ); - var results = { - // directoryName: matches[ 1 ], // (tschw) currently unused - nodeName: matches[ 2 ], - objectName: matches[ 3 ], - objectIndex: matches[ 4 ], - propertyName: matches[ 5 ], // required - propertyIndex: matches[ 6 ] - }; + } - var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' ); + var results = { + // directoryName: matches[ 1 ], // (tschw) currently unused + nodeName: matches[ 2 ], + objectName: matches[ 3 ], + objectIndex: matches[ 4 ], + propertyName: matches[ 5 ], // required + propertyIndex: matches[ 6 ] + }; - if ( lastDot !== undefined && lastDot !== - 1 ) { + var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' ); - var objectName = results.nodeName.substring( lastDot + 1 ); + if ( lastDot !== undefined && lastDot !== - 1 ) { - // Object names must be checked against a whitelist. Otherwise, there - // is no way to parse 'foo.bar.baz': 'baz' must be a property, but - // 'bar' could be the objectName, or part of a nodeName (which can - // include '.' characters). - if ( supportedObjectNames.indexOf( objectName ) !== - 1 ) { + var objectName = results.nodeName.substring( lastDot + 1 ); - results.nodeName = results.nodeName.substring( 0, lastDot ); - results.objectName = objectName; + // Object names must be checked against a whitelist. Otherwise, there + // is no way to parse 'foo.bar.baz': 'baz' must be a property, but + // 'bar' could be the objectName, or part of a nodeName (which can + // include '.' characters). + if ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) { - } + results.nodeName = results.nodeName.substring( 0, lastDot ); + results.objectName = objectName; } - if ( results.propertyName === null || results.propertyName.length === 0 ) { + } - throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName ); + if ( results.propertyName === null || results.propertyName.length === 0 ) { - } + throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName ); - return results; + } - }; + return results; - }(), + }, findNode: function ( root, nodeName ) { @@ -44642,6 +44235,7 @@ this.near = near || 0; this.far = far || Infinity; + this.camera = null; this.params = { Mesh: {}, @@ -44708,13 +44302,13 @@ this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize(); - this._camera = camera; + this.camera = camera; } else if ( ( camera && camera.isOrthographicCamera ) ) { this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ); - this._camera = camera; + this.camera = camera; } else { @@ -44914,6 +44508,8 @@ * @author bhouston / http://clara.io */ + var _vector$6 = new Vector2(); + function Box2( min, max ) { this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity ); @@ -44946,21 +44542,15 @@ }, - setFromCenterAndSize: function () { + setFromCenterAndSize: function ( center, size ) { - var v1 = new Vector2(); - - return function setFromCenterAndSize( center, size ) { - - var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); - - return this; + var halfSize = _vector$6.copy( size ).multiplyScalar( 0.5 ); + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - }; + return this; - }(), + }, clone: function () { @@ -45102,18 +44692,12 @@ }, - distanceToPoint: function () { - - var v1 = new Vector2(); - - return function distanceToPoint( point ) { - - var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); - return clampedPoint.sub( point ).length(); + distanceToPoint: function ( point ) { - }; + var clampedPoint = _vector$6.copy( point ).clamp( this.min, this.max ); + return clampedPoint.sub( point ).length(); - }(), + }, intersect: function ( box ) { @@ -45154,7 +44738,8 @@ * @author bhouston / http://clara.io */ - var _startP, _startEnd; + var _startP = new Vector3(); + var _startEnd = new Vector3(); function Line3( start, end ) { @@ -45242,13 +44827,6 @@ closestPointToPointParameter: function ( point, clampToLine ) { - if ( _startP === undefined ) { - - _startP = new Vector3(); - _startEnd = new Vector3(); - - } - _startP.subVectors( point, this.start ); _startEnd.subVectors( this.end, this.start ); @@ -45322,6 +44900,11 @@ * @author WestLangley / http://github.com/WestLangley */ + var _v1$5 = new Vector3(); + var _v2$3 = new Vector3(); + var _normalMatrix$1 = new Matrix3(); + var _keys = [ 'a', 'b', 'c' ]; + function VertexNormalsHelper( object, size, hex, linewidth ) { this.object = object; @@ -45369,97 +44952,87 @@ VertexNormalsHelper.prototype = Object.create( LineSegments.prototype ); VertexNormalsHelper.prototype.constructor = VertexNormalsHelper; - VertexNormalsHelper.prototype.update = ( function () { - - var v1 = new Vector3(); - var v2 = new Vector3(); - var normalMatrix = new Matrix3(); - - return function update() { + VertexNormalsHelper.prototype.update = function () { - var keys = [ 'a', 'b', 'c' ]; + this.object.updateMatrixWorld( true ); - this.object.updateMatrixWorld( true ); + _normalMatrix$1.getNormalMatrix( this.object.matrixWorld ); - normalMatrix.getNormalMatrix( this.object.matrixWorld ); + var matrixWorld = this.object.matrixWorld; - var matrixWorld = this.object.matrixWorld; + var position = this.geometry.attributes.position; - var position = this.geometry.attributes.position; - - // - - var objGeometry = this.object.geometry; + // - if ( objGeometry && objGeometry.isGeometry ) { + var objGeometry = this.object.geometry; - var vertices = objGeometry.vertices; + if ( objGeometry && objGeometry.isGeometry ) { - var faces = objGeometry.faces; + var vertices = objGeometry.vertices; - var idx = 0; + var faces = objGeometry.faces; - for ( var i = 0, l = faces.length; i < l; i ++ ) { + var idx = 0; - var face = faces[ i ]; + for ( var i = 0, l = faces.length; i < l; i ++ ) { - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { + var face = faces[ i ]; - var vertex = vertices[ face[ keys[ j ] ] ]; + for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { - var normal = face.vertexNormals[ j ]; + var vertex = vertices[ face[ _keys[ j ] ] ]; - v1.copy( vertex ).applyMatrix4( matrixWorld ); + var normal = face.vertexNormals[ j ]; - v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); + _v1$5.copy( vertex ).applyMatrix4( matrixWorld ); - position.setXYZ( idx, v1.x, v1.y, v1.z ); + _v2$3.copy( normal ).applyMatrix3( _normalMatrix$1 ).normalize().multiplyScalar( this.size ).add( _v1$5 ); - idx = idx + 1; + position.setXYZ( idx, _v1$5.x, _v1$5.y, _v1$5.z ); - position.setXYZ( idx, v2.x, v2.y, v2.z ); + idx = idx + 1; - idx = idx + 1; + position.setXYZ( idx, _v2$3.x, _v2$3.y, _v2$3.z ); - } + idx = idx + 1; } - } else if ( objGeometry && objGeometry.isBufferGeometry ) { + } - var objPos = objGeometry.attributes.position; + } else if ( objGeometry && objGeometry.isBufferGeometry ) { - var objNorm = objGeometry.attributes.normal; + var objPos = objGeometry.attributes.position; - var idx = 0; + var objNorm = objGeometry.attributes.normal; - // for simplicity, ignore index and drawcalls, and render every normal + var idx = 0; - for ( var j = 0, jl = objPos.count; j < jl; j ++ ) { + // for simplicity, ignore index and drawcalls, and render every normal - v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld ); + for ( var j = 0, jl = objPos.count; j < jl; j ++ ) { - v2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) ); + _v1$5.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld ); - v2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); + _v2$3.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) ); - position.setXYZ( idx, v1.x, v1.y, v1.z ); + _v2$3.applyMatrix3( _normalMatrix$1 ).normalize().multiplyScalar( this.size ).add( _v1$5 ); - idx = idx + 1; + position.setXYZ( idx, _v1$5.x, _v1$5.y, _v1$5.z ); - position.setXYZ( idx, v2.x, v2.y, v2.z ); + idx = idx + 1; - idx = idx + 1; + position.setXYZ( idx, _v2$3.x, _v2$3.y, _v2$3.z ); - } + idx = idx + 1; } - position.needsUpdate = true; + } - }; + position.needsUpdate = true; - }() ); + }; /** * @author alteredq / http://alteredqualia.com/ @@ -45467,6 +45040,8 @@ * @author WestLangley / http://github.com/WestLangley */ + var _vector$7 = new Vector3(); + function SpotLightHelper( light, color ) { Object3D.call( this ); @@ -45524,34 +45099,28 @@ SpotLightHelper.prototype.update = function () { - var vector = new Vector3(); - - return function update() { - - this.light.updateMatrixWorld(); - - var coneLength = this.light.distance ? this.light.distance : 1000; - var coneWidth = coneLength * Math.tan( this.light.angle ); + this.light.updateMatrixWorld(); - this.cone.scale.set( coneWidth, coneWidth, coneLength ); + var coneLength = this.light.distance ? this.light.distance : 1000; + var coneWidth = coneLength * Math.tan( this.light.angle ); - vector.setFromMatrixPosition( this.light.target.matrixWorld ); + this.cone.scale.set( coneWidth, coneWidth, coneLength ); - this.cone.lookAt( vector ); + _vector$7.setFromMatrixPosition( this.light.target.matrixWorld ); - if ( this.color !== undefined ) { + this.cone.lookAt( _vector$7 ); - this.cone.material.color.set( this.color ); + if ( this.color !== undefined ) { - } else { + this.cone.material.color.set( this.color ); - this.cone.material.color.copy( this.light.color ); + } else { - } + this.cone.material.color.copy( this.light.color ); - }; + } - }(); + }; /** * @author Sean Griffin / http://twitter.com/sgrif @@ -45561,6 +45130,10 @@ * @author Mugen87 / https://github.com/Mugen87 */ + var _vector$8 = new Vector3(); + var _boneMatrix = new Matrix4(); + var _matrixWorldInv = new Matrix4(); + function getBoneList( object ) { var boneList = []; @@ -45626,49 +45199,40 @@ SkeletonHelper.prototype = Object.create( LineSegments.prototype ); SkeletonHelper.prototype.constructor = SkeletonHelper; - SkeletonHelper.prototype.updateMatrixWorld = function () { - - var vector = new Vector3(); - - var boneMatrix = new Matrix4(); - var matrixWorldInv = new Matrix4(); + SkeletonHelper.prototype.updateMatrixWorld = function ( force ) { - return function updateMatrixWorld( force ) { + var bones = this.bones; - var bones = this.bones; - - var geometry = this.geometry; - var position = geometry.getAttribute( 'position' ); - - matrixWorldInv.getInverse( this.root.matrixWorld ); + var geometry = this.geometry; + var position = geometry.getAttribute( 'position' ); - for ( var i = 0, j = 0; i < bones.length; i ++ ) { + _matrixWorldInv.getInverse( this.root.matrixWorld ); - var bone = bones[ i ]; + for ( var i = 0, j = 0; i < bones.length; i ++ ) { - if ( bone.parent && bone.parent.isBone ) { + var bone = bones[ i ]; - boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld ); - vector.setFromMatrixPosition( boneMatrix ); - position.setXYZ( j, vector.x, vector.y, vector.z ); + if ( bone.parent && bone.parent.isBone ) { - boneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld ); - vector.setFromMatrixPosition( boneMatrix ); - position.setXYZ( j + 1, vector.x, vector.y, vector.z ); + _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld ); + _vector$8.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j, _vector$8.x, _vector$8.y, _vector$8.z ); - j += 2; + _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld ); + _vector$8.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j + 1, _vector$8.x, _vector$8.y, _vector$8.z ); - } + j += 2; } - geometry.getAttribute( 'position' ).needsUpdate = true; + } - Object3D.prototype.updateMatrixWorld.call( this, force ); + geometry.getAttribute( 'position' ).needsUpdate = true; - }; + Object3D.prototype.updateMatrixWorld.call( this, force ); - }(); + }; /** * @author alteredq / http://alteredqualia.com/ @@ -45838,6 +45402,10 @@ * @author Mugen87 / https://github.com/Mugen87 */ + var _vector$9 = new Vector3(); + var _color1 = new Color(); + var _color2 = new Color(); + function HemisphereLightHelper( light, size, color ) { Object3D.call( this ); @@ -45879,43 +45447,34 @@ HemisphereLightHelper.prototype.update = function () { - var vector = new Vector3(); + var mesh = this.children[ 0 ]; - var color1 = new Color(); - var color2 = new Color(); - - return function update() { - - var mesh = this.children[ 0 ]; - - if ( this.color !== undefined ) { - - this.material.color.set( this.color ); - - } else { + if ( this.color !== undefined ) { - var colors = mesh.geometry.getAttribute( 'color' ); + this.material.color.set( this.color ); - color1.copy( this.light.color ); - color2.copy( this.light.groundColor ); + } else { - for ( var i = 0, l = colors.count; i < l; i ++ ) { + var colors = mesh.geometry.getAttribute( 'color' ); - var color = ( i < ( l / 2 ) ) ? color1 : color2; + _color1.copy( this.light.color ); + _color2.copy( this.light.groundColor ); - colors.setXYZ( i, color.r, color.g, color.b ); + for ( var i = 0, l = colors.count; i < l; i ++ ) { - } + var color = ( i < ( l / 2 ) ) ? _color1 : _color2; - colors.needsUpdate = true; + colors.setXYZ( i, color.r, color.g, color.b ); } - mesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() ); + colors.needsUpdate = true; - }; + } - }(); + mesh.lookAt( _vector$9.setFromMatrixPosition( this.light.matrixWorld ).negate() ); + + }; /** * @author WestLangley / http://github.com/WestLangley @@ -46055,17 +45614,13 @@ LightProbeHelper.prototype.onBeforeRender = function () { - return function update() { - - this.position.copy( this.lightProbe.position ); - - this.scale.set( 1, 1, 1 ).multiplyScalar( this.size ); + this.position.copy( this.lightProbe.position ); - this.material.uniforms.intensity.value = this.lightProbe.intensity; + this.scale.set( 1, 1, 1 ).multiplyScalar( this.size ); - }; + this.material.uniforms.intensity.value = this.lightProbe.intensity; - }(); + }; /** * @author mrdoob / http://mrdoob.com/ @@ -46323,6 +45878,10 @@ * @author WestLangley / http://github.com/WestLangley */ + var _v1$6 = new Vector3(); + var _v2$4 = new Vector3(); + var _normalMatrix$2 = new Matrix3(); + function FaceNormalsHelper( object, size, hex, linewidth ) { // FaceNormalsHelper only supports THREE.Geometry @@ -46371,61 +45930,53 @@ FaceNormalsHelper.prototype = Object.create( LineSegments.prototype ); FaceNormalsHelper.prototype.constructor = FaceNormalsHelper; - FaceNormalsHelper.prototype.update = ( function () { - - var v1 = new Vector3(); - var v2 = new Vector3(); - var normalMatrix = new Matrix3(); + FaceNormalsHelper.prototype.update = function () { - return function update() { + this.object.updateMatrixWorld( true ); - this.object.updateMatrixWorld( true ); + _normalMatrix$2.getNormalMatrix( this.object.matrixWorld ); - normalMatrix.getNormalMatrix( this.object.matrixWorld ); + var matrixWorld = this.object.matrixWorld; - var matrixWorld = this.object.matrixWorld; + var position = this.geometry.attributes.position; - var position = this.geometry.attributes.position; - - // - - var objGeometry = this.object.geometry; + // - var vertices = objGeometry.vertices; + var objGeometry = this.object.geometry; - var faces = objGeometry.faces; + var vertices = objGeometry.vertices; - var idx = 0; + var faces = objGeometry.faces; - for ( var i = 0, l = faces.length; i < l; i ++ ) { + var idx = 0; - var face = faces[ i ]; + for ( var i = 0, l = faces.length; i < l; i ++ ) { - var normal = face.normal; + var face = faces[ i ]; - v1.copy( vertices[ face.a ] ) - .add( vertices[ face.b ] ) - .add( vertices[ face.c ] ) - .divideScalar( 3 ) - .applyMatrix4( matrixWorld ); + var normal = face.normal; - v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); + _v1$6.copy( vertices[ face.a ] ) + .add( vertices[ face.b ] ) + .add( vertices[ face.c ] ) + .divideScalar( 3 ) + .applyMatrix4( matrixWorld ); - position.setXYZ( idx, v1.x, v1.y, v1.z ); + _v2$4.copy( normal ).applyMatrix3( _normalMatrix$2 ).normalize().multiplyScalar( this.size ).add( _v1$6 ); - idx = idx + 1; + position.setXYZ( idx, _v1$6.x, _v1$6.y, _v1$6.z ); - position.setXYZ( idx, v2.x, v2.y, v2.z ); + idx = idx + 1; - idx = idx + 1; + position.setXYZ( idx, _v2$4.x, _v2$4.y, _v2$4.z ); - } + idx = idx + 1; - position.needsUpdate = true; + } - }; + position.needsUpdate = true; - }() ); + }; /** * @author alteredq / http://alteredqualia.com/ @@ -46433,6 +45984,10 @@ * @author WestLangley / http://github.com/WestLangley */ + var _v1$7 = new Vector3(); + var _v2$5 = new Vector3(); + var _v3$1 = new Vector3(); + function DirectionalLightHelper( light, size, color ) { Object3D.call( this ); @@ -46485,36 +46040,28 @@ DirectionalLightHelper.prototype.update = function () { - var v1 = new Vector3(); - var v2 = new Vector3(); - var v3 = new Vector3(); - - return function update() { - - v1.setFromMatrixPosition( this.light.matrixWorld ); - v2.setFromMatrixPosition( this.light.target.matrixWorld ); - v3.subVectors( v2, v1 ); + _v1$7.setFromMatrixPosition( this.light.matrixWorld ); + _v2$5.setFromMatrixPosition( this.light.target.matrixWorld ); + _v3$1.subVectors( _v2$5, _v1$7 ); - this.lightPlane.lookAt( v2 ); + this.lightPlane.lookAt( _v2$5 ); - if ( this.color !== undefined ) { - - this.lightPlane.material.color.set( this.color ); - this.targetLine.material.color.set( this.color ); + if ( this.color !== undefined ) { - } else { + this.lightPlane.material.color.set( this.color ); + this.targetLine.material.color.set( this.color ); - this.lightPlane.material.color.copy( this.light.color ); - this.targetLine.material.color.copy( this.light.color ); + } else { - } + this.lightPlane.material.color.copy( this.light.color ); + this.targetLine.material.color.copy( this.light.color ); - this.targetLine.lookAt( v2 ); - this.targetLine.scale.z = v3.length(); + } - }; + this.targetLine.lookAt( _v2$5 ); + this.targetLine.scale.z = _v3$1.length(); - }(); + }; /** * @author alteredq / http://alteredqualia.com/ @@ -46526,6 +46073,9 @@ * http://evanw.github.com/lightgl.js/tests/shadowmap.html */ + var _vector$a = new Vector3(); + var _camera = new Camera(); + function CameraHelper( camera ) { var geometry = new BufferGeometry(); @@ -46635,91 +46185,84 @@ CameraHelper.prototype.update = function () { - var geometry, pointMap; - - var vector = new Vector3(); - var camera = new Camera(); - - function setPoint( point, x, y, z ) { - - vector.set( x, y, z ).unproject( camera ); - - var points = pointMap[ point ]; + var geometry = this.geometry; + var pointMap = this.pointMap; - if ( points !== undefined ) { + var w = 1, h = 1; - var position = geometry.getAttribute( 'position' ); + // we need just camera projection matrix inverse + // world matrix must be identity - for ( var i = 0, l = points.length; i < l; i ++ ) { + _camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse ); - position.setXYZ( points[ i ], vector.x, vector.y, vector.z ); + // center / target - } + setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 ); + setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 ); - } + // near - } + setPoint( 'n1', pointMap, geometry, _camera, - w, - h, - 1 ); + setPoint( 'n2', pointMap, geometry, _camera, w, - h, - 1 ); + setPoint( 'n3', pointMap, geometry, _camera, - w, h, - 1 ); + setPoint( 'n4', pointMap, geometry, _camera, w, h, - 1 ); - return function update() { + // far - geometry = this.geometry; - pointMap = this.pointMap; + setPoint( 'f1', pointMap, geometry, _camera, - w, - h, 1 ); + setPoint( 'f2', pointMap, geometry, _camera, w, - h, 1 ); + setPoint( 'f3', pointMap, geometry, _camera, - w, h, 1 ); + setPoint( 'f4', pointMap, geometry, _camera, w, h, 1 ); - var w = 1, h = 1; + // up - // we need just camera projection matrix inverse - // world matrix must be identity + setPoint( 'u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, - 1 ); + setPoint( 'u2', pointMap, geometry, _camera, - w * 0.7, h * 1.1, - 1 ); + setPoint( 'u3', pointMap, geometry, _camera, 0, h * 2, - 1 ); - camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse ); + // cross - // center / target + setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 ); + setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 ); + setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 ); + setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 ); - setPoint( 'c', 0, 0, - 1 ); - setPoint( 't', 0, 0, 1 ); + setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 ); + setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 ); + setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 ); + setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 ); - // near + geometry.getAttribute( 'position' ).needsUpdate = true; - setPoint( 'n1', - w, - h, - 1 ); - setPoint( 'n2', w, - h, - 1 ); - setPoint( 'n3', - w, h, - 1 ); - setPoint( 'n4', w, h, - 1 ); + }; - // far + function setPoint( point, pointMap, geometry, camera, x, y, z ) { - setPoint( 'f1', - w, - h, 1 ); - setPoint( 'f2', w, - h, 1 ); - setPoint( 'f3', - w, h, 1 ); - setPoint( 'f4', w, h, 1 ); + _vector$a.set( x, y, z ).unproject( camera ); - // up + var points = pointMap[ point ]; - setPoint( 'u1', w * 0.7, h * 1.1, - 1 ); - setPoint( 'u2', - w * 0.7, h * 1.1, - 1 ); - setPoint( 'u3', 0, h * 2, - 1 ); + if ( points !== undefined ) { - // cross + var position = geometry.getAttribute( 'position' ); - setPoint( 'cf1', - w, 0, 1 ); - setPoint( 'cf2', w, 0, 1 ); - setPoint( 'cf3', 0, - h, 1 ); - setPoint( 'cf4', 0, h, 1 ); + for ( var i = 0, l = points.length; i < l; i ++ ) { - setPoint( 'cn1', - w, 0, - 1 ); - setPoint( 'cn2', w, 0, - 1 ); - setPoint( 'cn3', 0, - h, - 1 ); - setPoint( 'cn4', 0, h, - 1 ); + position.setXYZ( points[ i ], _vector$a.x, _vector$a.y, _vector$a.z ); - geometry.getAttribute( 'position' ).needsUpdate = true; + } - }; + } - }(); + } /** * @author mrdoob / http://mrdoob.com/ * @author Mugen87 / http://github.com/Mugen87 */ + var _box$2 = new Box3(); + function BoxHelper( object, color ) { this.object = object; @@ -46744,64 +46287,59 @@ BoxHelper.prototype = Object.create( LineSegments.prototype ); BoxHelper.prototype.constructor = BoxHelper; - BoxHelper.prototype.update = ( function () { + BoxHelper.prototype.update = function ( object ) { + + if ( object !== undefined ) { - var box = new Box3(); + console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' ); - return function update( object ) { + } - if ( object !== undefined ) { + if ( this.object !== undefined ) { - console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' ); + _box$2.setFromObject( this.object ); - } + } - if ( this.object !== undefined ) { + if ( _box$2.isEmpty() ) return; - box.setFromObject( this.object ); + var min = _box$2.min; + var max = _box$2.max; - } + /* + 5____4 + 1/___0/| + | 6__|_7 + 2/___3/ + + 0: max.x, max.y, max.z + 1: min.x, max.y, max.z + 2: min.x, min.y, max.z + 3: max.x, min.y, max.z + 4: max.x, max.y, min.z + 5: min.x, max.y, min.z + 6: min.x, min.y, min.z + 7: max.x, min.y, min.z + */ - if ( box.isEmpty() ) return; + var position = this.geometry.attributes.position; + var array = position.array; - var min = box.min; - var max = box.max; + array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z; + array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z; + array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z; + array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z; + array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z; + array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z; + array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z; + array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z; - /* - 5____4 - 1/___0/| - | 6__|_7 - 2/___3/ - - 0: max.x, max.y, max.z - 1: min.x, max.y, max.z - 2: min.x, min.y, max.z - 3: max.x, min.y, max.z - 4: max.x, max.y, min.z - 5: min.x, max.y, min.z - 6: min.x, min.y, min.z - 7: max.x, min.y, min.z - */ - - var position = this.geometry.attributes.position; - var array = position.array; - - array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z; - array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z; - array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z; - array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z; - array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z; - array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z; - array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z; - array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z; - - position.needsUpdate = true; - - this.geometry.computeBoundingSphere(); + position.needsUpdate = true; + + this.geometry.computeBoundingSphere(); - }; - } )(); + }; BoxHelper.prototype.setFromObject = function ( object ) { @@ -46944,7 +46482,8 @@ * headWidth - Number */ - var lineGeometry, coneGeometry; + var _axis = new Vector3(); + var _lineGeometry, _coneGeometry; function ArrowHelper( dir, origin, length, color, headLength, headWidth ) { @@ -46959,23 +46498,23 @@ if ( headLength === undefined ) headLength = 0.2 * length; if ( headWidth === undefined ) headWidth = 0.2 * headLength; - if ( lineGeometry === undefined ) { + if ( _lineGeometry === undefined ) { - lineGeometry = new BufferGeometry(); - lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); + _lineGeometry = new BufferGeometry(); + _lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); - coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); - coneGeometry.translate( 0, - 0.5, 0 ); + _coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); + _coneGeometry.translate( 0, - 0.5, 0 ); } this.position.copy( origin ); - this.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) ); + this.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color } ) ); this.line.matrixAutoUpdate = false; this.add( this.line ); - this.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) ); + this.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color } ) ); this.cone.matrixAutoUpdate = false; this.add( this.cone ); @@ -46987,36 +46526,29 @@ ArrowHelper.prototype = Object.create( Object3D.prototype ); ArrowHelper.prototype.constructor = ArrowHelper; - ArrowHelper.prototype.setDirection = ( function () { - - var axis = new Vector3(); - var radians; - - return function setDirection( dir ) { - - // dir is assumed to be normalized + ArrowHelper.prototype.setDirection = function ( dir ) { - if ( dir.y > 0.99999 ) { + // dir is assumed to be normalized - this.quaternion.set( 0, 0, 0, 1 ); + if ( dir.y > 0.99999 ) { - } else if ( dir.y < - 0.99999 ) { + this.quaternion.set( 0, 0, 0, 1 ); - this.quaternion.set( 1, 0, 0, 0 ); + } else if ( dir.y < - 0.99999 ) { - } else { + this.quaternion.set( 1, 0, 0, 0 ); - axis.set( dir.z, 0, - dir.x ).normalize(); + } else { - radians = Math.acos( dir.y ); + _axis.set( dir.z, 0, - dir.x ).normalize(); - this.quaternion.setFromAxisAngle( axis, radians ); + var radians = Math.acos( dir.y ); - } + this.quaternion.setFromAxisAngle( _axis, radians ); - }; + } - }() ); + }; ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) { @@ -47606,17 +47138,10 @@ }, getPosition: function () { - var v1; - - return function getPosition() { + console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); + return new Vector3().setFromMatrixColumn( this, 3 ); - if ( v1 === undefined ) v1 = new Vector3(); - console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); - return v1.setFromMatrixColumn( this, 3 ); - - }; - - }(), + }, setRotationFromQuaternion: function ( q ) { console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); @@ -49373,6 +48898,7 @@ exports.UnsignedShort5551Type = UnsignedShort5551Type; exports.UnsignedShort565Type = UnsignedShort565Type; exports.UnsignedShortType = UnsignedShortType; + exports.VSMShadowMap = VSMShadowMap; exports.Vector2 = Vector2; exports.Vector3 = Vector3; exports.Vector4 = Vector4; diff --git a/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.min.js b/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.min.js index 771edccb..af2a3848 100644 --- a/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.min.js +++ b/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.min.js @@ -1,613 +1,620 @@ // threejs.org/license -(function(l,na){"object"===typeof exports&&"undefined"!==typeof module?na(exports):"function"===typeof define&&define.amd?define(["exports"],na):(l=l||self,na(l.THREE={}))})(this,function(l){function na(){}function D(a,b){this.x=a||0;this.y=b||0}function da(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}function n(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function ja(){this.elements=[1,0,0,0,1,0,0,0,1];0c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a}function qe(a){return.04045>a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}function re(a){return.0031308> -a?12.92*a:1.055*Math.pow(a,.41666)-.055}function Ub(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new C;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex=void 0!==f?f:0}function S(){Object.defineProperty(this,"id",{value:kg++});this.uuid=O.generateUUID();this.name="";this.type="Material";this.lights=this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors= -0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.stencilFunc=519;this.stencilRef=0;this.stencilMask=255;this.stencilZPass=this.stencilZFail=this.stencilFail=7680;this.stencilWrite=!1;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1; -this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.visible=!0;this.userData={};this.needsUpdate=!0}function la(a){S.call(this);this.type="MeshBasicMaterial";this.color=new C(16777215);this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin= -this.wireframeLinecap="round";this.lights=this.morphTargets=this.skinning=!1;this.setValues(a)}function M(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.name="";this.array=a;this.itemSize=b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0}function Fc(a,b,c){M.call(this,new Int8Array(a),b,c)}function Gc(a,b,c){M.call(this,new Uint8Array(a),b,c)}function Hc(a,b, -c){M.call(this,new Uint8ClampedArray(a),b,c)}function Ic(a,b,c){M.call(this,new Int16Array(a),b,c)}function xb(a,b,c){M.call(this,new Uint16Array(a),b,c)}function Jc(a,b,c){M.call(this,new Int32Array(a),b,c)}function yb(a,b,c){M.call(this,new Uint32Array(a),b,c)}function E(a,b,c){M.call(this,new Float32Array(a),b,c)}function Kc(a,b,c){M.call(this,new Float64Array(a),b,c)}function gf(){this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights= -[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1}function hf(a){if(0===a.length)return-Infinity;for(var b=a[0],c=1,d=a.length;cb&&(b=a[c]);return b}function B(){Object.defineProperty(this,"id",{value:lg+=2});this.uuid=O.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere= -this.boundingBox=null;this.drawRange={start:0,count:Infinity};this.userData={}}function sa(a,b){G.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new B;this.material=void 0!==b?b:new la({color:16777215*Math.random()});this.drawMode=0;this.updateMorphTargets()}function N(){Object.defineProperty(this,"id",{value:mg+=2});this.uuid=O.generateUUID();this.name="";this.type="Geometry";this.vertices=[];this.colors=[];this.faces=[];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphNormals=[];this.skinWeights= -[];this.skinIndices=[];this.lineDistances=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.lineDistancesNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.uvsNeedUpdate=this.verticesNeedUpdate=this.elementsNeedUpdate=!1}function Vb(a,b,c,d,e,f){N.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new kb(a,b,c,d,e,f));this.mergeVertices()}function kb(a,b,c,d,e,f){function g(a, -b,c,d,e,f,g,t,xa,ya,F){var q=f/xa,v=g/ya,x=f/2,y=g/2,A=t/2;g=xa+1;var H=ya+1,Fa=f=0,T,w,z=new n;for(w=0;wg;g++)a.setRenderTarget(f,g),a.clear(b,c,d);a.setRenderTarget(e)}}function mb(a,b,c){Va.call(this,a,b,c)}function Bb(a,b,c,d,e,f,g,h,k,m,r,p){Y.call(this,null,f,g,h,k,m,d,e,r,p);this.image={data:a,width:b,height:c};this.magFilter=void 0!==k?k:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1}function Ya(a,b){this.normal=void 0!==a?a:new n(1,0,0);this.constant=void 0!== -b?b:0}function Fd(a,b,c,d,e,f){this.planes=[void 0!==a?a:new Ya,void 0!==b?b:new Ya,void 0!==c?c:new Ya,void 0!==d?d:new Ya,void 0!==e?e:new Ya,void 0!==f?f:new Ya]}function se(){function a(e,f){!1!==c&&(d(e,f),b.requestAnimationFrame(a))}var b=null,c=!1,d=null;return{start:function(){!0!==c&&null!==d&&(b.requestAnimationFrame(a),c=!0)},stop:function(){c=!1},setAnimationLoop:function(a){d=a},setContext:function(a){b=a}}}function ng(a){function b(b,c){var d=b.array,e=b.dynamic?35048:35044,h=a.createBuffer(); -a.bindBuffer(c,h);a.bufferData(c,d,e);b.onUploadCallback();c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:h,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,version:b.version}}var c=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&& -(a=a.data);return c.get(a)},remove:function(b){b.isInterleavedBufferAttribute&&(b=b.data);var d=c.get(b);d&&(a.deleteBuffer(d.buffer),c.delete(b))},update:function(d,e){d.isInterleavedBufferAttribute&&(d=d.data);var f=c.get(d);if(void 0===f)c.set(d,b(d,e));else if(f.versionm;m++){if(p=d[m])if(h=p[0],k=p[1]){r&&e.addAttribute("morphTarget"+m,r[h]);f&&e.addAttribute("morphNormal"+m,f[h]);c[m]=k;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function yg(a,b){var c={};return{update:function(d){var e=b.render.frame,f=d.geometry,g=a.get(d,f);c[g.id]!==e&&(f.isGeometry&&g.updateFromObject(d),a.update(g),c[g.id]=e);return g},dispose:function(){c={}}}}function db(a,b,c,d,e,f,g,h,k,m){a= -void 0!==a?a:[];Y.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g?g:1022,h,k,m);this.flipY=!1}function Xb(a,b,c,d){Y.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Yb(a,b,c,d){Y.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Zb(a,b,c){var d=a[0];if(0>=d||0/gm,function(a,c){a=P[c];if(void 0===a)throw Error("Can not resolve #include <"+c+">");return ue(a)})}function zf(a){return a.replace(/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,c,d,e){a="";for(c=parseInt(c);cc;c++)b.probe.push(new n);var d=new n,e=new Q,f=new Q;return{setup:function(c,h,k){for(var g=0,r=0,p=0,u=0;9>u;u++)b.probe[u].set(0,0,0);var l=0,q=0,v=0,n=0,A=0;k=k.matrixWorldInverse;u=0;for(var w=c.length;uya;ya++)b.probe[ya].addScaledVector(y.sh.coefficients[ya],H);else if(y.isDirectionalLight){var F= -a.get(y);F.color.copy(y.color).multiplyScalar(y.intensity);F.direction.setFromMatrixPosition(y.matrixWorld);d.setFromMatrixPosition(y.target.matrixWorld);F.direction.sub(d);F.direction.transformDirection(k);if(F.shadow=y.castShadow)H=y.shadow,F.shadowBias=H.bias,F.shadowRadius=H.radius,F.shadowMapSize=H.mapSize;b.directionalShadowMap[l]=ya;b.directionalShadowMatrix[l]=y.shadow.matrix;b.directional[l]=F;l++}else if(y.isSpotLight){F=a.get(y);F.position.setFromMatrixPosition(y.matrixWorld);F.position.applyMatrix4(k); -F.color.copy(z).multiplyScalar(H);F.distance=xa;F.direction.setFromMatrixPosition(y.matrixWorld);d.setFromMatrixPosition(y.target.matrixWorld);F.direction.sub(d);F.direction.transformDirection(k);F.coneCos=Math.cos(y.angle);F.penumbraCos=Math.cos(y.angle*(1-y.penumbra));F.decay=y.decay;if(F.shadow=y.castShadow)H=y.shadow,F.shadowBias=H.bias,F.shadowRadius=H.radius,F.shadowMapSize=H.mapSize;b.spotShadowMap[v]=ya;b.spotShadowMatrix[v]=y.shadow.matrix;b.spot[v]=F;v++}else if(y.isRectAreaLight)F=a.get(y), -F.color.copy(z).multiplyScalar(H),F.position.setFromMatrixPosition(y.matrixWorld),F.position.applyMatrix4(k),f.identity(),e.copy(y.matrixWorld),e.premultiply(k),f.extractRotation(e),F.halfWidth.set(.5*y.width,0,0),F.halfHeight.set(0,.5*y.height,0),F.halfWidth.applyMatrix4(f),F.halfHeight.applyMatrix4(f),b.rectArea[n]=F,n++;else if(y.isPointLight){F=a.get(y);F.position.setFromMatrixPosition(y.matrixWorld);F.position.applyMatrix4(k);F.color.copy(y.color).multiplyScalar(y.intensity);F.distance=y.distance; -F.decay=y.decay;if(F.shadow=y.castShadow)H=y.shadow,F.shadowBias=H.bias,F.shadowRadius=H.radius,F.shadowMapSize=H.mapSize,F.shadowCameraNear=H.camera.near,F.shadowCameraFar=H.camera.far;b.pointShadowMap[q]=ya;b.pointShadowMatrix[q]=y.shadow.matrix;b.point[q]=F;q++}else y.isHemisphereLight&&(F=a.get(y),F.direction.setFromMatrixPosition(y.matrixWorld),F.direction.transformDirection(k),F.direction.normalize(),F.skyColor.copy(y.color).multiplyScalar(H),F.groundColor.copy(y.groundColor).multiplyScalar(H), -b.hemi[A]=F,A++)}b.ambient[0]=g;b.ambient[1]=r;b.ambient[2]=p;c=b.hash;if(c.directionalLength!==l||c.pointLength!==q||c.spotLength!==v||c.rectAreaLength!==n||c.hemiLength!==A||c.shadowsLength!==h.length)b.directional.length=l,b.spot.length=v,b.rectArea.length=n,b.point.length=q,b.hemi.length=A,c.directionalLength=l,c.pointLength=q,c.spotLength=v,c.rectAreaLength=n,c.hemiLength=A,c.shadowsLength=h.length,b.version=sh++},state:b}}function Bf(){var a=new rh,b=[],c=[];return{init:function(){b.length= -0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)},pushShadow:function(a){c.push(a)}}}function th(){function a(c){c=c.target;c.removeEventListener("dispose",a);delete b[c.id]}var b={};return{get:function(c,d){if(void 0===b[c.id]){var e=new Bf;b[c.id]={};b[c.id][d.id]=e;c.addEventListener("dispose",a)}else void 0===b[c.id][d.id]?(e=new Bf,b[c.id][d.id]=e):e=b[c.id][d.id];return e},dispose:function(){b={}}}}function ob(a){S.call(this); -this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.lights=this.fog=!1;this.setValues(a)}function pb(a){S.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance=1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale= -1;this.displacementBias=0;this.lights=this.fog=!1;this.setValues(a)}function Cf(a,b,c){function d(b,c,d,e,f,g){var h=b.geometry;var k=p;var m=b.customDepthMaterial;d&&(k=l,m=b.customDistanceMaterial);m?k=m:(m=!1,c.morphTargets&&(h&&h.isBufferGeometry?m=h.morphAttributes&&h.morphAttributes.position&&0d||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?O.floorPowerOfTwo:Math.floor,b=d(e*a.width),e=d(e*a.height),void 0=== -zb&&(zb=h(b,e)),c=c?h(b,e):zb,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return O.isPowerOfTwo(a.width)&&O.isPowerOfTwo(a.height)}function r(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function p(b,c,e,f){a.generateMipmap(b); -d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function l(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead."); -return d}function t(a){return 1003===a||1004===a||1005===a?9728:9729}function q(b){b=b.target;b.removeEventListener("dispose",q);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&delete lb[b.id];g.memory.textures--}function v(b){b=b.target;b.removeEventListener("dispose",v);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e= -0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.memory.textures--}function n(a,b){var e=d.get(a);if(a.isVideoTexture){var f=a.id,h=g.render.frame;lb[f]!==h&&(lb[f]=h,a.update())}if(0q;q++)t[q]=g||u?u?b.image[q].image: -b.image[q]:k(b.image[q],!1,!0,e.maxCubemapSize);var v=t[0],n=m(v)||e.isWebGL2,x=f.convert(b.format),T=f.convert(b.type),w=l(x,T);y(34067,b,n);for(q=0;6>q;q++)if(g)for(var H,A=t[q].mipmaps,Fa=0,F=A.length;Fa=e.maxTextures&&console.warn("THREE.WebGLTextures: Trying to use "+a+" texture units while this GPU supports only "+e.maxTextures);E+=1;return a};this.resetTextureUnits=function(){E=0};this.setTexture2D=n;this.setTexture2DArray=function(a,b){var e=d.get(a);0q;q++)h.__webglFramebuffer[q]=a.createFramebuffer();else if(h.__webglFramebuffer=a.createFramebuffer(),q)if(e.isWebGL2){h.__webglMultisampledFramebuffer= -a.createFramebuffer();h.__webglColorRenderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,h.__webglColorRenderbuffer);q=f.convert(b.texture.format);var x=f.convert(b.texture.type);q=l(q,x);x=F(b);a.renderbufferStorageMultisample(36161,x,q,b.width,b.height);a.bindFramebuffer(36160,h.__webglMultisampledFramebuffer);a.framebufferRenderbuffer(36160,36064,36161,h.__webglColorRenderbuffer);a.bindRenderbuffer(36161,null);b.depthBuffer&&(h.__webglDepthRenderbuffer=a.createRenderbuffer(),D(h.__webglDepthRenderbuffer, -b,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.");if(u){c.bindTexture(34067,k.__webglTexture);y(34067,b.texture,t);for(q=0;6>q;q++)xa(h.__webglFramebuffer[q],b,36064,34069+q);r(b.texture,t)&&p(34067,b.texture,b.width,b.height);c.bindTexture(34067,null)}else c.bindTexture(3553,k.__webglTexture),y(3553,b.texture,t),xa(h.__webglFramebuffer,b,36064,3553),r(b.texture,t)&&p(3553,b.texture,b.width,b.height),c.bindTexture(3553, -null);if(b.depthBuffer){h=d.get(b);k=!0===b.isWebGLRenderTargetCube;if(b.depthTexture){if(k)throw Error("target.depthTexture not supported in Cube render targets");if(b&&b.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(36160,h.__webglFramebuffer);if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&&b.depthTexture.image.width=== -b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0);n(b.depthTexture,0);h=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(36160,36096,3553,h,0);else if(1027===b.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,h,0);else throw Error("Unknown depthTexture format");}else if(k)for(h.__webglDepthbuffer=[],k=0;6>k;k++)a.bindFramebuffer(36160,h.__webglFramebuffer[k]), -h.__webglDepthbuffer[k]=a.createRenderbuffer(),D(h.__webglDepthbuffer[k],b);else a.bindFramebuffer(36160,h.__webglFramebuffer),h.__webglDepthbuffer=a.createRenderbuffer(),D(h.__webglDepthbuffer,b);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap=function(a){var b=a.texture,f=m(a)||e.isWebGL2;if(r(b,f)){f=a.isWebGLRenderTargetCube?34067:3553;var g=d.get(b).__webglTexture;c.bindTexture(f,g);p(f,b,a.width,a.height);c.bindTexture(f,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(e.isWebGL2){var c= -d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer);c=b.width;var f=b.height,g=16384;b.depthBuffer&&(g|=256);b.stencilBuffer&&(g|=1024);a.blitFramebuffer(0,0,c,f,0,0,c,f,g,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===G&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."), -G=!0),a=a.texture);n(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLRenderTargetCube&&(!1===B&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."),B=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?A(a,b):w(a,b)}}function Ef(a,b,c){return{convert:function(a){if(1E3===a)return 10497;if(1001===a)return 33071;if(1002===a)return 33648;if(1003===a)return 9728;if(1004===a)return 9984; -if(1005===a)return 9986;if(1006===a)return 9729;if(1007===a)return 9985;if(1008===a)return 9987;if(1009===a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)return 33635;if(1010===a)return 5120;if(1011===a)return 5122;if(1012===a)return 5123;if(1013===a)return 5124;if(1014===a)return 5125;if(1015===a)return 5126;if(1016===a){if(c.isWebGL2)return 5131;var d=b.get("OES_texture_half_float");if(null!==d)return d.HALF_FLOAT_OES}if(1021===a)return 6406;if(1022===a)return 6407;if(1023=== -a)return 6408;if(1024===a)return 6409;if(1025===a)return 6410;if(1026===a)return 6402;if(1027===a)return 34041;if(1028===a)return 6403;if(100===a)return 32774;if(101===a)return 32778;if(102===a)return 32779;if(200===a)return 0;if(201===a)return 1;if(202===a)return 768;if(203===a)return 769;if(204===a)return 770;if(205===a)return 771;if(206===a)return 772;if(207===a)return 773;if(208===a)return 774;if(209===a)return 775;if(210===a)return 776;if(33776===a||33777===a||33778===a||33779===a)if(d=b.get("WEBGL_compressed_texture_s3tc"), -null!==d){if(33776===a)return d.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777===a)return d.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===a)return d.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return d.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(35840===a||35841===a||35842===a||35843===a)if(d=b.get("WEBGL_compressed_texture_pvrtc"),null!==d){if(35840===a)return d.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(35841===a)return d.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return d.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return d.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(36196=== -a&&(d=b.get("WEBGL_compressed_texture_etc1"),null!==d))return d.COMPRESSED_RGB_ETC1_WEBGL;if(37808===a||37809===a||37810===a||37811===a||37812===a||37813===a||37814===a||37815===a||37816===a||37817===a||37818===a||37819===a||37820===a||37821===a)if(d=b.get("WEBGL_compressed_texture_astc"),null!==d)return a;if(103===a||104===a){if(c.isWebGL2){if(103===a)return 32775;if(104===a)return 32776}d=b.get("EXT_blend_minmax");if(null!==d){if(103===a)return d.MIN_EXT;if(104===a)return d.MAX_EXT}}if(1020===a){if(c.isWebGL2)return 34042; -d=b.get("WEBGL_depth_texture");if(null!==d)return d.UNSIGNED_INT_24_8_WEBGL}return 0}}}function $b(){G.call(this);this.type="Group"}function Qc(a){ka.call(this);this.cameras=a||[]}function Ff(a,b,c){Gf.setFromMatrixPosition(b.matrixWorld);Hf.setFromMatrixPosition(c.matrixWorld);var d=Gf.distanceTo(Hf),e=b.projectionMatrix.elements,f=c.projectionMatrix.elements,g=e[14]/(e[10]-1);c=e[14]/(e[10]+1);var h=(e[9]+1)/e[5],k=(e[9]-1)/e[5],m=(e[8]-1)/e[0],r=(f[8]+1)/f[0];e=g*m;f=g*r;r=d/(-m+r);m=r*-m;b.matrixWorld.decompose(a.position, -a.quaternion,a.scale);a.translateX(m);a.translateZ(r);a.matrixWorld.compose(a.position,a.quaternion,a.scale);a.matrixWorldInverse.getInverse(a.matrixWorld);b=g+r;g=c+r;a.projectionMatrix.makePerspective(e-m,f+(d-m),h*c/g*b,k*c/g*b,b,g)}function ve(a){function b(){return null!==h&&!0===h.isPresenting}function c(){if(b()){var c=h.getEyeParameters("left");e=2*c.renderWidth*t;f=c.renderHeight*t;xa=a.getPixelRatio();a.getSize(H);a.setDrawingBufferSize(e,f,1);w.viewport.set(0,0,e/2,f);y.viewport.set(e/ -2,0,e/2,f);F.start();g.dispatchEvent({type:"sessionstart"})}else g.enabled&&a.setDrawingBufferSize(H.width,H.height,xa),F.stop(),g.dispatchEvent({type:"sessionend"})}function d(a,b){null!==b&&4===b.length&&a.set(b[0]*e,b[1]*f,b[2]*e,b[3]*f)}var e,f,g=this,h=null,k=null,m=null,r=[],p=new Q,l=new Q,t=1,q="local-floor";"undefined"!==typeof window&&"VRFrameData"in window&&(k=new window.VRFrameData,window.addEventListener("vrdisplaypresentchange",c,!1));var v=new Q,x=new da,A=new n,w=new ka;w.viewport= -new ea;w.layers.enable(1);var y=new ka;y.viewport=new ea;y.layers.enable(2);var z=new Qc([w,y]);z.layers.enable(1);z.layers.enable(2);var H=new D,xa,ya=[];this.enabled=!1;this.getController=function(a){var b=r[a];void 0===b&&(b=new $b,b.matrixAutoUpdate=!1,b.visible=!1,r[a]=b);return b};this.getDevice=function(){return h};this.setDevice=function(a){void 0!==a&&(h=a);F.setContext(a)};this.setFramebufferScaleFactor=function(a){t=a};this.setReferenceSpaceType=function(a){q=a};this.setPoseTarget=function(a){void 0!== -a&&(m=a)};this.getCamera=function(a){var c="local-floor"===q?1.6:0;if(!1===b())return a.position.set(0,c,0),a.rotation.set(0,0,0),a;h.depthNear=a.near;h.depthFar=a.far;h.getFrameData(k);if("local-floor"===q){var e=h.stageParameters;e?p.fromArray(e.sittingToStandingTransform):p.makeTranslation(0,c,0)}c=k.pose;e=null!==m?m:a;e.matrix.copy(p);e.matrix.decompose(e.position,e.quaternion,e.scale);null!==c.orientation&&(x.fromArray(c.orientation),e.quaternion.multiply(x));null!==c.position&&(x.setFromRotationMatrix(p), -A.fromArray(c.position),A.applyQuaternion(x),e.position.add(A));e.updateMatrixWorld();w.near=a.near;y.near=a.near;w.far=a.far;y.far=a.far;w.matrixWorldInverse.fromArray(k.leftViewMatrix);y.matrixWorldInverse.fromArray(k.rightViewMatrix);l.getInverse(p);"local-floor"===q&&(w.matrixWorldInverse.multiply(l),y.matrixWorldInverse.multiply(l));a=e.parent;null!==a&&(v.getInverse(a.matrixWorld),w.matrixWorldInverse.multiply(v),y.matrixWorldInverse.multiply(v));w.matrixWorld.getInverse(w.matrixWorldInverse); -y.matrixWorld.getInverse(y.matrixWorldInverse);w.projectionMatrix.fromArray(k.leftProjectionMatrix);y.projectionMatrix.fromArray(k.rightProjectionMatrix);Ff(z,w,y);a=h.getLayers();a.length&&(a=a[0],d(w.viewport,a.leftBounds),d(y.viewport,a.rightBounds));a:for(a=0;af.matrixWorld.determinant();ca.setMaterial(e, -h);var k=l(a,c,e,f),m=!1;if(b!==d.id||P!==k.id||W!==(!0===e.wireframe))b=d.id,P=k.id,W=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(Aa.update(f,d,e,k),m=!0);h=d.index;var r=d.attributes.position;c=1;!0===e.wireframe&&(h=wa.getWireframeAttribute(d),c=2);a=Ba;if(null!==h){var p=ta.get(h);a=Da;a.setIndex(p)}if(m){if(d&&d.isInstancedBufferGeometry&&!Ga.isWebGL2&&null===ma.get("ANGLE_instanced_arrays"))console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays."); -else{ca.initAttributes();m=d.attributes;k=k.getAttributes();var u=e.defaultAttributeValues;for(z in k){var q=k[z];if(0<=q){var t=m[z];if(void 0!==t){var n=t.normalized,v=t.itemSize,x=ta.get(t);if(void 0!==x){var w=x.buffer,y=x.type;x=x.bytesPerElement;if(t.isInterleavedBufferAttribute){var A=t.data,H=A.stride;t=t.offset;A&&A.isInstancedInterleavedBuffer?(ca.enableAttributeAndDivisor(q,A.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=A.meshPerAttribute*A.count)):ca.enableAttribute(q); -L.bindBuffer(34962,w);L.vertexAttribPointer(q,v,y,n,H*x,t*x)}else t.isInstancedBufferAttribute?(ca.enableAttributeAndDivisor(q,t.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=t.meshPerAttribute*t.count)):ca.enableAttribute(q),L.bindBuffer(34962,w),L.vertexAttribPointer(q,v,y,n,0,0)}}else if(void 0!==u&&(n=u[z],void 0!==n))switch(n.length){case 2:L.vertexAttrib2fv(q,n);break;case 3:L.vertexAttrib3fv(q,n);break;case 4:L.vertexAttrib4fv(q,n);break;default:L.vertexAttrib1fv(q,n)}}}ca.disableUnusedAttributes()}null!== -h&&L.bindBuffer(34963,p.buffer)}p=Infinity;null!==h?p=h.count:void 0!==r&&(p=r.count);h=d.drawRange.start*c;r=null!==g?g.start*c:0;var z=Math.max(h,r);g=Math.max(0,Math.min(p,h+d.drawRange.count*c,r+(null!==g?g.count*c:Infinity))-1-z+1);if(0!==g){if(f.isMesh)if(!0===e.wireframe)ca.setLineWidth(e.wireframeLinewidth*(null===Ha?ba:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),ca.setLineWidth(e* -(null===Ha?ba:1)),f.isLineSegments?a.setMode(1):f.isLineLoop?a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);d&&d.isInstancedBufferGeometry?0c;c++){var p=r[h[c]];var l=r[h[(c+1)%3]];f[0]=Math.min(p,l);f[1]=Math.max(p,l);p=f[0]+","+f[1];void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]})}}for(p in g)m=g[p],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new n,null!==a.index){k=a.attributes.position;r=a.index;var t=a.groups;0===t.length&&(t=[{start:0,count:r.count,materialIndex:0}]); -a=0;for(e=t.length;ac;c++)p=r.getX(m+c),l=r.getX(m+(c+1)%3),f[0]=Math.min(p,l),f[1]=Math.max(p,l),p=f[0]+","+f[1],void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]});for(p in g)m=g[p],h.fromBufferAttribute(k,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(k,m.index2),b.push(h.x,h.y,h.z)}else for(k=a.attributes.position,m=0,d=k.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(k, -g),b.push(h.x,h.y,h.z);this.addAttribute("position",new E(b,3))}function Xc(a,b,c){N.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new ec(a,b,c));this.mergeVertices()}function ec(a,b,c){B.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,k=new n,m=new n,r=new n,p=new n,l,t;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter."); -var q=b+1;for(l=0;l<=c;l++){var v=l/c;for(t=0;t<=b;t++){var x=t/b;a(x,v,k);e.push(k.x,k.y,k.z);0<=x-1E-5?(a(x-1E-5,v,m),r.subVectors(k,m)):(a(x+1E-5,v,m),r.subVectors(m,k));0<=v-1E-5?(a(x,v-1E-5,m),p.subVectors(k,m)):(a(x,v+1E-5,m),p.subVectors(m,k));h.crossVectors(r,p).normalize();f.push(h.x,h.y,h.z);g.push(x,v)}}for(l=0;ld&&1===a.x&&(k[b]=a.x-1);0===c.x&&0===c.z&&(k[b]=d/2/Math.PI+.5)}B.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a, -indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],k=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(k[a+0]+=1),.2>c&&(k[a+2]+=1),.2>d&&(k[a+4]+=1))})();this.addAttribute("position",new E(h,3));this.addAttribute("normal",new E(h.slice(),3));this.addAttribute("uv",new E(k,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Zc(a, -b){N.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new fc(a,b));this.mergeVertices()}function fc(a,b){Aa.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function $c(a,b){N.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Eb(a,b));this.mergeVertices()}function Eb(a,b){Aa.call(this,[1,0,0, --1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function ad(a,b){N.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new gc(a,b));this.mergeVertices()}function gc(a,b){var c=(1+Math.sqrt(5))/2;Aa.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5, -11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function bd(a,b){N.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new hc(a,b));this.mergeVertices()}function hc(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;Aa.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c, -0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function cd(a,b,c,d,e,f){N.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d, -closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new Fb(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function Fb(a,b,c,d,e){function f(e){r=a.getPointAt(e/b,r);var f=g.normals[e];e=g.binormals[e];for(l=0;l<=d;l++){var m=l/d*Math.PI*2,p=Math.sin(m);m=-Math.cos(m);k.x=m*f.x+p*e.x;k.y=m*f.y+p*e.y;k.z=m*f.z+p*e.z;k.normalize();q.push(k.x,k.y,k.z);h.x=r.x+c*k.x;h.y=r.y+c*k.y;h.z= -r.z+c*k.z;t.push(h.x,h.y,h.z)}}B.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,k=new n,m=new D,r=new n,p,l,t=[],q=[],v=[],x=[];for(p=0;p=b;e-=d)f=Lf(e,a[e],a[e+1],f);f&&Gb(f,f.next)&&(fd(f),f=f.next);return f}function gd(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!Gb(a,a.next)&&0!==fa(a.prev,a,a.next))a=a.next;else{fd(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b} -function hd(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,k=h;do null===k.z&&(k.z=ze(k.x,k.y,d,e,f)),k.prevZ=k.prev,k=k.nextZ=k.next;while(k!==h);k.prevZ.nextZ=null;k.prevZ=null;h=k;var m,r,p,l,t=1;do{k=h;var q=h=null;for(r=0;k;){r++;var n=k;for(m=p=0;mn!==q.next.y>n&&q.next.y!==q.y&&p<(q.next.x-q.x)*(n-q.y)/(q.next.y-q.y)+q.x&&(r=!r),q=q.next;while(q!==k);q=r}k=q}if(k){a=Nf(g,h);g=gd(g,g.next);a=gd(a,a.next);hd(g,b,c,d,e,f);hd(a,b,c,d,e,f);break a}h= -h.next}g=g.next}while(g!==a)}break}}}}function wh(a,b,c,d){var e=a.prev,f=a.next;if(0<=fa(e,a,f))return!1;var g=e.x>a.x?e.x>f.x?e.x:f.x:a.x>f.x?a.x:f.x,h=e.y>a.y?e.y>f.y?e.y:f.y:a.y>f.y?a.y:f.y,k=ze(e.x=k&&d&&d.z<=b;){if(c!==a.prev&&c!==a.next&&kc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=fa(c.prev,c,c.next))return!1;c=c.prevZ;if(d!==a.prev&&d!==a.next&&kc(e.x,e.y,a.x,a.y, -f.x,f.y,d.x,d.y)&&0<=fa(d.prev,d,d.next))return!1;d=d.nextZ}for(;c&&c.z>=k;){if(c!==a.prev&&c!==a.next&&kc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=fa(c.prev,c,c.next))return!1;c=c.prevZ}for(;d&&d.z<=b;){if(d!==a.prev&&d!==a.next&&kc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=fa(d.prev,d,d.next))return!1;d=d.nextZ}return!0}function xh(a,b){return a.x-b.x}function yh(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f= -g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&kc(eh.x)&&id(c,a)&&(h=c,m=r)}c=c.next}return h}function ze(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b| -b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function zh(a){var b=a,c=a;do{if(b.xfa(a.prev,a,a.next)?0<=fa(a,b,a.next)&&0<=fa(a,a.prev,b):0>fa(a,b,a.prev)||0>fa(a,a.next,b)}function Nf(a,b){var c=new Ae(a.i,a.x,a.y),d=new Ae(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function Lf(a,b,c,d){a=new Ae(a,b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function fd(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ= -a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function Ae(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function Of(a){var b=a.length;2Number.EPSILON){var k=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/k;b=b.y+d/k;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new D(f,d);e=Math.sqrt(e/2)}else a=!1,d>Number.EPSILON?f>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)=== -Math.sign(g)&&(a=!0),a?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new D(f/e,d/e)}function h(a,b){for(K=a.length;0<=--K;){var c=K;var f=K-1;0>f&&(f=a.length-1);var g,h=w+2*F;for(g=0;gl;l++){var p=m[f[l]];var n=m[f[(l+1)%3]];d[0]=Math.min(p,n);d[1]=Math.max(p,n);p=d[0]+","+d[1];void 0===e[p]?e[p]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[p].face2=h}for(p in e)if(d=e[p],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new E(c,3))}function Kb(a,b,c,d, -e,f,g,h){N.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new fb(a,b,c,d,e,f,g,h));this.mergeVertices()}function fb(a,b,c,d,e,f,g,h){function k(c){var e,f=new D,k=new n,r=0,v=!0===c?a:b,w=!0===c?1:-1;var E=q;for(e=1;e<=d;e++)p.push(0,x*w,0),u.push(0,w,0),t.push(.5,.5),q++;var C=q;for(e=0;e<=d;e++){var B=e/d*h+g,G=Math.cos(B);B=Math.sin(B);k.x=v*B;k.y=x*w; -k.z=v*G;p.push(k.x,k.y,k.z);u.push(0,w,0);f.x=.5*G+.5;f.y=.5*B*w+.5;t.push(f.x,f.y);q++}for(e=0;ethis.duration&&this.resetDuration()}function Bh(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return rc;case "vector":case "vector2":case "vector3":case "vector4":return sc; -case "color":return Pd;case "quaternion":return rd;case "bool":case "boolean":return Od;case "string":return Rd}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function Ch(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=Bh(a.type);if(void 0===a.times){var c=[],d=[];aa.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)}function Be(a,b,c){var d=this,e= -!1,f=0,g=0,h=void 0;this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()};this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this}}function Na(a){this.manager=void 0!==a?a:Ba}function Sf(a){this.manager= -void 0!==a?a:Ba}function Tf(a){this.manager=void 0!==a?a:Ba;this._parser=null}function Ce(a){this.manager=void 0!==a?a:Ba;this._parser=null}function sd(a){this.manager=void 0!==a?a:Ba}function De(a){this.manager=void 0!==a?a:Ba}function Sd(a){this.manager=void 0!==a?a:Ba}function J(){this.type="Curve";this.arcLengthDivisions=200}function Ca(a,b,c,d,e,f,g,h){J.call(this);this.type="EllipseCurve";this.aX=a||0;this.aY=b||0;this.xRadius=c||1;this.yRadius=d||1;this.aStartAngle=e||0;this.aEndAngle=f||2* -Math.PI;this.aClockwise=g||!1;this.aRotation=h||0}function tc(a,b,c,d,e,f){Ca.call(this,a,b,c,c,d,e,f);this.type="ArcCurve"}function Ee(){var a=0,b=0,c=0,d=0;return{initCatmullRom:function(e,f,g,h,k){e=k*(g-e);h=k*(h-f);a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},initNonuniformCatmullRom:function(e,f,g,h,k,m,l){e=((f-e)/k-(g-e)/(k+m)+(g-f)/m)*m;h=((g-f)/m-(h-f)/(m+l)+(h-g)/l)*m;a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},calc:function(e){var f=e*e;return a+b*e+c*f+d*f*e}}}function wa(a,b,c,d){J.call(this); -this.type="CatmullRomCurve3";this.points=a||[];this.closed=b||!1;this.curveType=c||"centripetal";this.tension=d||.5}function Uf(a,b,c,d,e){b=.5*(d-b);e=.5*(e-c);var f=a*a;return(2*c-2*d+b+e)*a*f+(-3*c+3*d-2*b-e)*f+b*a+c}function td(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}function ud(a,b,c,d,e){var f=1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}function Oa(a,b,c,d){J.call(this);this.type="CubicBezierCurve";this.v0=a||new D;this.v1=b||new D;this.v2=c||new D;this.v3=d||new D}function bb(a, -b,c,d){J.call(this);this.type="CubicBezierCurve3";this.v0=a||new n;this.v1=b||new n;this.v2=c||new n;this.v3=d||new n}function Da(a,b){J.call(this);this.type="LineCurve";this.v1=a||new D;this.v2=b||new D}function Pa(a,b){J.call(this);this.type="LineCurve3";this.v1=a||new n;this.v2=b||new n}function Qa(a,b,c){J.call(this);this.type="QuadraticBezierCurve";this.v0=a||new D;this.v1=b||new D;this.v2=c||new D}function cb(a,b,c){J.call(this);this.type="QuadraticBezierCurve3";this.v0=a||new n;this.v1=b|| -new n;this.v2=c||new n}function Ra(a){J.call(this);this.type="SplineCurve";this.points=a||[]}function gb(){J.call(this);this.type="CurvePath";this.curves=[];this.autoClose=!1}function Sa(a){gb.call(this);this.type="Path";this.currentPoint=new D;a&&this.setFromPoints(a)}function tb(a){Sa.call(this,a);this.uuid=O.generateUUID();this.type="Shape";this.holes=[]}function R(a,b){G.call(this);this.type="Light";this.color=new C(a);this.intensity=void 0!==b?b:1;this.receiveShadow=void 0}function Td(a,b,c){R.call(this, -a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(G.DefaultUp);this.updateMatrix();this.groundColor=new C(b)}function Sb(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new D(512,512);this.map=null;this.matrix=new Q}function Ud(){Sb.call(this,new ka(50,1,.5,500))}function Vd(a,b,c,d,e,f){R.call(this,a,b);this.type="SpotLight";this.position.copy(G.DefaultUp);this.updateMatrix();this.target=new G;Object.defineProperty(this,"power",{get:function(){return this.intensity* -Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Ud}function Wd(a,b,c,d){R.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",{get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new Sb(new ka(90,1,.5,500))}function vd(a,b,c,d,e,f){Xa.call(this); -this.type="OrthographicCamera";this.zoom=1;this.view=null;this.left=void 0!==a?a:-1;this.right=void 0!==b?b:1;this.top=void 0!==c?c:1;this.bottom=void 0!==d?d:-1;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()}function Xd(){Sb.call(this,new vd(-5,5,5,-5,.5,500))}function Yd(a,b){R.call(this,a,b);this.type="DirectionalLight";this.position.copy(G.DefaultUp);this.updateMatrix();this.target=new G;this.shadow=new Xd}function Zd(a,b){R.call(this,a,b);this.type="AmbientLight"; -this.castShadow=void 0}function $d(a,b,c,d){R.call(this,a,b);this.type="RectAreaLight";this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function ae(a){this.manager=void 0!==a?a:Ba;this.textures={}}function be(){B.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function ce(a,b,c,d){"number"===typeof c&&(d=c,c=!1,console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument."));M.call(this,a,b,c);this.meshPerAttribute= -d||1}function Fe(a){this.manager=void 0!==a?a:Ba}function Ge(a){this.manager=void 0!==a?a:Ba;this.resourcePath=""}function He(a){"undefined"===typeof createImageBitmap&&console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported.");"undefined"===typeof fetch&&console.warn("THREE.ImageBitmapLoader: fetch() not supported.");this.manager=void 0!==a?a:Ba;this.options=void 0}function Ie(){this.type="ShapePath";this.color=new C;this.subPaths=[];this.currentPath=null}function Je(a){this.type= -"Font";this.data=a}function Vf(a){this.manager=void 0!==a?a:Ba}function wd(){}function Ke(a){this.manager=void 0!==a?a:Ba}function de(){this.coefficients=[];for(var a=0;9>a;a++)this.coefficients.push(new n)}function Ta(a,b){R.call(this,void 0,b);this.sh=void 0!==a?a:new de}function Le(a,b,c){Ta.call(this,void 0,c);a=(new C).set(a);c=(new C).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c);this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)} -function Me(a,b){Ta.call(this,void 0,b);a=(new C).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))}function Wf(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new ka;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new ka;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1}function Ne(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function Oe(){G.call(this); -this.type="AudioListener";this.context=Pe.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0}function uc(a){G.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty"; -this.filters=[]}function Qe(a){uc.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function Re(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function Se(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select; -break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function Xf(a,b,c){c=c||qa.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function qa(a,b,c){this.path=b;this.parsedPath=c||qa.parseTrackName(b);this.node=qa.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Yf(){this.uuid=O.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var a={};this._indicesByUUID= -a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function Zf(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null); -c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function Te(a){this._root=a;this._initMemoryManager(); -this.time=this._accuIndex=0;this.timeScale=1}function ee(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Ue(a,b,c){Db.call(this,a,b);this.meshPerAttribute=c||1}function $f(a,b,c,d){this.ray=new wb(a,b);this.near=c||0;this.far=d||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points."); -return this.Points}}})}function ag(a,b){return a.distance-b.distance}function Ve(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new E(b,3));b=new W({fog:!1});this.cone=new U(a,b);this.add(this.cone);this.update()}function dg(a){var b=[];a&&a.isBone&&b.push(a);for(var c= -0;ca?-1:0b;b++)a[b]=(16>b?"0":"")+b.toString(16);return function(){var b=4294967295*Math.random()|0,d=4294967295*Math.random()|0,e=4294967295* -Math.random()|0,f=4294967295*Math.random()|0;return(a[b&255]+a[b>>8&255]+a[b>>16&255]+a[b>>24&255]+"-"+a[d&255]+a[d>>8&255]+"-"+a[d>>16&15|64]+a[d>>24&255]+"-"+a[e&63|128]+a[e>>8&255]+"-"+a[e>>16&255]+a[e>>24&255]+a[f&255]+a[f>>8&255]+a[f>>16&255]+a[f>>24&255]).toUpperCase()}}(),clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},lerp:function(a,b,c){return(1-c)*a+c*b},smoothstep:function(a, -b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(a){return a*O.DEG2RAD},radToDeg:function(a){return a*O.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2, -Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(D.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(D.prototype,{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this}, -setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."), -this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this}, -subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y=a[1]*b+a[4]*c+a[7];return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this}, -max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y); -return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x* -this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+ -Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromBufferAttribute:function(a, -b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(da,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h=c[d+0],k=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var l=e[f+1],p=e[f+2];e=e[f+3];if(c!==e||h!==d||k!==l||m!== -p){f=1-g;var n=h*d+k*l+m*p+c*e,t=0<=n?1:-1,q=1-n*n;q>Number.EPSILON&&(q=Math.sqrt(q),n=Math.atan2(q,n*t),f=Math.sin(f*n)/q,g=Math.sin(g*n)/q);t*=g;h=h*f+d*t;k=k*f+l*t;m=m*f+p*t;c=c*f+e*t;f===1-g&&(g=1/Math.sqrt(h*h+k*k+m*m+c*c),h*=g,k*=g,m*=g,c*=g)}a[b]=h;a[b+1]=k;a[b+2]=m;a[b+3]=c}});Object.defineProperties(da.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z}, -set:function(a){this._z=a;this._onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this._onChangeCallback()}}});Object.assign(da.prototype,{isQuaternion:!0,set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x=a.x;this._y=a.y;this._z=a.z;this._w=a.w;this._onChangeCallback();return this},setFromEuler:function(a,b){if(!a|| -!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),k=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f-c*d*e):"YXZ"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f+c*d*e):"ZXY"===a?(this._x=c*k*f-h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e+c*d*f,this._w= -h*k*f-c*d*e):"ZYX"===a?(this._x=c*k*f-h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f+c*d*e):"YZX"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f-c*d*e):"XZY"===a&&(this._x=c*k*f-h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f+c*d*e);!1!==b&&this._onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b);this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);this._onChangeCallback();return this},setFromRotationMatrix:function(a){var b= -a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6];b=b[10];var m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+k)/c,this._z=.25*c);this._onChangeCallback();return this},setFromUnitVectors:function(a, -b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z=a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(O.clamp(this.dot(a),-1,1)))},rotateTowards:function(a,b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},conjugate:function(){this._x*= --1;this._y*=-1;this._z*=-1;this._onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this._onChangeCallback();return this}, -multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w;var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;this._onChangeCallback(); -return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g*f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize(),this._onChangeCallback(),this;a=Math.sqrt(a);var h=Math.atan2(a, -g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this._onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+ -3]=this._w;return a},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});Object.assign(n.prototype,{isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+ -a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this}, -addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this}, -subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a=new da; -return function(b){b&&b.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(a.setFromEuler(b))}}(),applyAxisAngle:function(){var a=new da;return function(b,c){return this.applyQuaternion(a.setFromAxisAngle(b,c))}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b= -this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,m=a*d+e*c-f*b;b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-m*-f;this.y=k*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-k*-e;return this},project:function(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)}, -unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z, -a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a,Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c|| -1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z= -0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)}, -lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this,a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this}, -projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(){var a=new n;return function(b){a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a=new n;return function(b){return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(O.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b= -this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)*a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta,a.y)},setFromCylindricalCoords:function(a, -b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,4*b)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z}, -fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});var jb;Object.assign(ja.prototype,{isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,k){var m=this.elements; -m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=k;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},applyToBufferAttribute:function(a){void 0=== -jb&&(jb=new n);for(var b=0,c=a.count;bh)return!1}return!0}function nb(a,b){this.center=void 0!==a?a:new n;this.radius=void 0!==b?b:0}function Sb(a,b){this.origin=void 0!==a?a:new n;this.direction=void 0!==b?b:new n}function ia(a,b,c){this.a=void 0!==a?a:new n;this.b=void 0!==b?b:new n;this.c=void 0!==c?c:new n}function J(a,b,c){return void 0===b&&void 0=== +c?this.set(a):this.setRGB(a,b,c)}function Sf(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a}function Tf(a){return.04045>a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}function Uf(a){return.0031308>a?12.92*a:1.055*Math.pow(a,.41666)-.055}function yc(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new J;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex= +void 0!==f?f:0}function Q(){Object.defineProperty(this,"id",{value:Ni++});this.uuid=O.generateUUID();this.name="";this.type="Material";this.lights=this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors=0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.stencilFunc=519;this.stencilRef=0;this.stencilMask= +255;this.stencilZPass=this.stencilZFail=this.stencilFail=7680;this.stencilWrite=!1;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.toneMapped=this.visible=!0;this.userData={};this.needsUpdate=!0}function ya(a){Q.call(this);this.type="MeshBasicMaterial";this.color=new J(16777215);this.lightMap= +this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.lights=this.morphTargets=this.skinning=!1;this.setValues(a)}function N(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.name="";this.array=a;this.itemSize= +b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0}function xd(a,b,c){N.call(this,new Int8Array(a),b,c)}function yd(a,b,c){N.call(this,new Uint8Array(a),b,c)}function zd(a,b,c){N.call(this,new Uint8ClampedArray(a),b,c)}function Ad(a,b,c){N.call(this,new Int16Array(a),b,c)}function Tb(a,b,c){N.call(this,new Uint16Array(a),b,c)}function Bd(a,b,c){N.call(this,new Int32Array(a),b,c)}function Ub(a,b,c){N.call(this,new Uint32Array(a), +b,c)}function A(a,b,c){N.call(this,new Float32Array(a),b,c)}function Cd(a,b,c){N.call(this,new Float64Array(a),b,c)}function dh(){this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1}function eh(a){if(0===a.length)return-Infinity;for(var b=a[0],c=1,d= +a.length;cb&&(b=a[c]);return b}function D(){Object.defineProperty(this,"id",{value:Oi+=2});this.uuid=O.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity};this.userData={}}function ra(a,b){B.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new ya({color:16777215*Math.random()});this.drawMode= +0;this.updateMorphTargets()}function fh(a,b,c,d,e,f,g,h){if(null===(1===b.side?d.intersectTriangle(g,f,e,!0,h):d.intersectTriangle(e,f,g,2!==b.side,h)))return null;De.copy(h);De.applyMatrix4(a.matrixWorld);b=c.ray.origin.distanceTo(De);return bc.far?null:{distance:b,point:De.clone(),object:a}}function Ee(a,b,c,d,e,f,g,h,l,m,p){Vb.fromBufferAttribute(e,l);Wb.fromBufferAttribute(e,m);Xb.fromBufferAttribute(e,p);e=a.morphTargetInfluences;if(b.morphTargets&&f&&e){Vf.set(0,0,0);Wf.set(0,0,0); +Xf.set(0,0,0);for(var u=0,r=f.length;ug;g++)a.setRenderTarget(f,g),a.clear(b,c,d);a.setRenderTarget(e)}}function Cb(a,b,c){Ka.call(this,a,b,c)}function Zb(a,b,c,d,e,f,g,h,l,m,p,u){ba.call(this,null,f,g,h,l,m,d,e,p,u);this.image={data:a,width:b,height:c};this.magFilter=void 0!==l?l:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1}function cb(a,b){this.normal=void 0!==a?a:new n(1,0,0);this.constant=void 0!==b?b:0}function Ed(a,b,c,d,e,f){this.planes=[void 0!==a?a: +new cb,void 0!==b?b:new cb,void 0!==c?c:new cb,void 0!==d?d:new cb,void 0!==e?e:new cb,void 0!==f?f:new cb]}function Zf(){function a(e,f){!1!==c&&(d(e,f),b.requestAnimationFrame(a))}var b=null,c=!1,d=null;return{start:function(){!0!==c&&null!==d&&(b.requestAnimationFrame(a),c=!0)},stop:function(){c=!1},setAnimationLoop:function(a){d=a},setContext:function(a){b=a}}}function Qi(a){function b(b,c){var d=b.array,e=b.dynamic?35048:35044,h=a.createBuffer();a.bindBuffer(c,h);a.bufferData(c,d,e);b.onUploadCallback(); +c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:h,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,version:b.version}}var c=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&&(a=a.data); +return c.get(a)},remove:function(b){b.isInterleavedBufferAttribute&&(b=b.data);var d=c.get(b);d&&(a.deleteBuffer(d.buffer),c.delete(b))},update:function(d,e){d.isInterleavedBufferAttribute&&(d=d.data);var f=c.get(d);if(void 0===f)c.set(d,b(d,e));else if(f.versionm;m++){if(u=d[m])if(h=u[0],l=u[1]){p&&e.addAttribute("morphTarget"+m,p[h]);f&&e.addAttribute("morphNormal"+m,f[h]);c[m]=l;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function aj(a,b){var c= +{};return{update:function(d){var e=b.render.frame,f=d.geometry,g=a.get(d,f);c[g.id]!==e&&(f.isGeometry&&g.updateFromObject(d),a.update(g),c[g.id]=e);return g},dispose:function(){c={}}}}function pb(a,b,c,d,e,f,g,h,l,m){a=void 0!==a?a:[];ba.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g?g:1022,h,l,m);this.flipY=!1}function Ec(a,b,c,d){ba.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Fc(a,b, +c,d){ba.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Gc(a,b,c){var d=a[0];if(0>=d||0/gm, +function(a,c){a=K[c];if(void 0===a)throw Error("Can not resolve #include <"+c+">");return ag(a)})}function zh(a){return a.replace(/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,c,d,e){a="";for(c=parseInt(c);cc;c++)b.probe.push(new n);var d=new n,e=new P,f=new P;return{setup:function(c,h,l){for(var g=0,p=0,u=0,k=0;9>k;k++)b.probe[k].set(0,0,0);var q=h=0,t=0,y=0,n=0,z=0,x=0,C=0;l=l.matrixWorldInverse;c.sort(Uj);k=0;for(var W=c.length;kCa;Ca++)b.probe[Ca].addScaledVector(E.sh.coefficients[Ca],v);else if(E.isDirectionalLight){var I=a.get(E);I.color.copy(E.color).multiplyScalar(E.intensity);I.direction.setFromMatrixPosition(E.matrixWorld);d.setFromMatrixPosition(E.target.matrixWorld);I.direction.sub(d);I.direction.transformDirection(l);if(I.shadow=E.castShadow)v=E.shadow,I.shadowBias=v.bias,I.shadowRadius=v.radius,I.shadowMapSize=v.mapSize,b.directionalShadowMap[h]=Ca,b.directionalShadowMatrix[h]= +E.shadow.matrix,z++;b.directional[h]=I;h++}else if(E.isSpotLight){I=a.get(E);I.position.setFromMatrixPosition(E.matrixWorld);I.position.applyMatrix4(l);I.color.copy(Fa).multiplyScalar(v);I.distance=A;I.direction.setFromMatrixPosition(E.matrixWorld);d.setFromMatrixPosition(E.target.matrixWorld);I.direction.sub(d);I.direction.transformDirection(l);I.coneCos=Math.cos(E.angle);I.penumbraCos=Math.cos(E.angle*(1-E.penumbra));I.decay=E.decay;if(I.shadow=E.castShadow)v=E.shadow,I.shadowBias=v.bias,I.shadowRadius= +v.radius,I.shadowMapSize=v.mapSize,b.spotShadowMap[t]=Ca,b.spotShadowMatrix[t]=E.shadow.matrix,C++;b.spot[t]=I;t++}else if(E.isRectAreaLight)I=a.get(E),I.color.copy(Fa).multiplyScalar(v),I.position.setFromMatrixPosition(E.matrixWorld),I.position.applyMatrix4(l),f.identity(),e.copy(E.matrixWorld),e.premultiply(l),f.extractRotation(e),I.halfWidth.set(.5*E.width,0,0),I.halfHeight.set(0,.5*E.height,0),I.halfWidth.applyMatrix4(f),I.halfHeight.applyMatrix4(f),b.rectArea[y]=I,y++;else if(E.isPointLight){I= +a.get(E);I.position.setFromMatrixPosition(E.matrixWorld);I.position.applyMatrix4(l);I.color.copy(E.color).multiplyScalar(E.intensity);I.distance=E.distance;I.decay=E.decay;if(I.shadow=E.castShadow)v=E.shadow,I.shadowBias=v.bias,I.shadowRadius=v.radius,I.shadowMapSize=v.mapSize,I.shadowCameraNear=v.camera.near,I.shadowCameraFar=v.camera.far,b.pointShadowMap[q]=Ca,b.pointShadowMatrix[q]=E.shadow.matrix,x++;b.point[q]=I;q++}else E.isHemisphereLight&&(I=a.get(E),I.direction.setFromMatrixPosition(E.matrixWorld), +I.direction.transformDirection(l),I.direction.normalize(),I.skyColor.copy(E.color).multiplyScalar(v),I.groundColor.copy(E.groundColor).multiplyScalar(v),b.hemi[n]=I,n++)}b.ambient[0]=g;b.ambient[1]=p;b.ambient[2]=u;c=b.hash;if(c.directionalLength!==h||c.pointLength!==q||c.spotLength!==t||c.rectAreaLength!==y||c.hemiLength!==n||c.numDirectionalShadows!==z||c.numPointShadows!==x||c.numSpotShadows!==C)b.directional.length=h,b.spot.length=t,b.rectArea.length=y,b.point.length=q,b.hemi.length=n,b.directionalShadowMap.length= +z,b.pointShadowMap.length=x,b.spotShadowMap.length=C,b.directionalShadowMatrix.length=z,b.pointShadowMatrix.length=x,b.spotShadowMatrix.length=C,c.directionalLength=h,c.pointLength=q,c.spotLength=t,c.rectAreaLength=y,c.hemiLength=n,c.numDirectionalShadows=z,c.numPointShadows=x,c.numSpotShadows=C,b.version=Wj++},state:b}}function Bh(){var a=new Vj,b=[],c=[];return{init:function(){b.length=0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)}, +pushShadow:function(a){c.push(a)}}}function Xj(){function a(c){c=c.target;c.removeEventListener("dispose",a);b.delete(c)}var b=new WeakMap;return{get:function(c,d){if(!1===b.has(c)){var e=new Bh;b.set(c,new WeakMap);b.get(c).set(d,e);c.addEventListener("dispose",a)}else!1===b.get(c).has(d)?(e=new Bh,b.get(c).set(d,e)):e=b.get(c).get(d);return e},dispose:function(){b=new WeakMap}}}function Eb(a){Q.call(this);this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap= +this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.lights=this.fog=!1;this.setValues(a)}function Fb(a){Q.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance=1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.lights=this.fog=!1;this.setValues(a)}function Ch(a,b,c){function d(b, +c,d,e,f,g){var h=b.geometry;var l=m;var r=b.customDepthMaterial;d.isPointLight&&(l=p,r=b.customDistanceMaterial);r?l=r:(r=!1,c.morphTargets&&(h&&h.isBufferGeometry?r=h.morphAttributes&&h.morphAttributes.position&&0\nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n \n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = decodeHalfRGBA ( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = pow( squared_mean - mean * mean, 0.5 );\n gl_FragColor = encodeHalfRGBA( vec2( mean, std_dev ) );\n}"}), +t=q.clone();t.defines.HORIZONAL_PASS=1;var n=new D;n.addAttribute("position",new N(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));var w=new ra(n,q);for(n=0;4!==n;++n){var z=0!==(n&1),x=0!==(n&2),C=new Eb({depthPacking:3201,morphTargets:z,skinning:x});m[n]=C;z=new Fb({morphTargets:z,skinning:x});p[n]=z}var W=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=1;this.render=function(d,m,p){if(!1!==W.enabled&&(!1!==W.autoUpdate||!1!==W.needsUpdate)&&0!==d.length){var u=a.getRenderTarget(), +k=a.getActiveCubeFace(),r=a.getActiveMipmapLevel(),n=a.state;n.setBlending(0);n.buffers.color.setClear(1,1,1,1);n.buffers.depth.setTest(!0);n.setScissorTest(!1);for(var y=0,x=d.length;yc||g.y>c)console.warn("THREE.WebGLShadowMap:",C,"has shadow exceeding max texture size, reducing"),g.x>c&&(h.x=Math.floor(c/U.x), +g.x=h.x*U.x,S.mapSize.x=h.x),g.y>c&&(h.y=Math.floor(c/U.y),g.y=h.y*U.y,S.mapSize.y=h.y);null!==S.map||S.isPointLightShadow||3!==this.type||(U={minFilter:1006,magFilter:1006,format:1023},S.map=new Ka(g.x,g.y,U),S.map.texture.name=C.name+".shadowMap",S.mapPass=new Ka(g.x,g.y,U),S.camera.updateProjectionMatrix());null===S.map&&(U={minFilter:1003,magFilter:1003,format:1023},S.map=new Ka(g.x,g.y,U),S.map.texture.name=C.name+".shadowMap",S.camera.updateProjectionMatrix());a.setRenderTarget(S.map);a.clear(); +U=S.getViewportCount();for(var z=0;zd||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?O.floorPowerOfTwo: +Math.floor,b=d(e*a.width),e=d(e*a.height),void 0===I&&(I=h(b,e)),c=c?h(b,e):I,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return O.isPowerOfTwo(a.width)&&O.isPowerOfTwo(a.height)}function p(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&& +1006!==a.minFilter}function u(b,c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function k(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead."); +return d}function q(a){return 1003===a||1004===a||1005===a?9728:9729}function t(b){b=b.target;b.removeEventListener("dispose",t);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&Ca.delete(b);g.memory.textures--}function n(b){b=b.target;b.removeEventListener("dispose",n);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e= +0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.memory.textures--}function w(a,b){var e=d.get(a);if(a.isVideoTexture){var f=g.render.frame;Ca.get(a)!==f&&(Ca.set(a,f),a.update())}if(0q;q++)t[q]=r||g?g?b.image[q].image: +b.image[q]:l(b.image[q],!1,!0,e.maxCubemapSize);var n=t[0],y=m(n)||e.isWebGL2,w=f.convert(b.format),x=f.convert(b.type),U=k(w,x);C(34067,b,y);if(r){for(q=0;6>q;q++){var S=t[q].mipmaps;for(r=0;rq;q++)if(g)for(c.texImage2D(34069+q,0,U,t[q].width,t[q].height,0,w,x,t[q].data),r=0;r=e.maxTextures&&console.warn("THREE.WebGLTextures: Trying to use "+a+" texture units while this GPU supports only "+e.maxTextures);H+=1;return a};this.resetTextureUnits=function(){H=0};this.setTexture2D=w;this.setTexture2DArray=function(a,b){var e=d.get(a);0q;q++)h.__webglFramebuffer[q]=a.createFramebuffer();else if(h.__webglFramebuffer=a.createFramebuffer(),q)if(e.isWebGL2){h.__webglMultisampledFramebuffer=a.createFramebuffer();h.__webglColorRenderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,h.__webglColorRenderbuffer);q=f.convert(b.texture.format);var y=f.convert(b.texture.type);q=k(q,y);y=B(b);a.renderbufferStorageMultisample(36161,y,q,b.width,b.height);a.bindFramebuffer(36160,h.__webglMultisampledFramebuffer); +a.framebufferRenderbuffer(36160,36064,36161,h.__webglColorRenderbuffer);a.bindRenderbuffer(36161,null);b.depthBuffer&&(h.__webglDepthRenderbuffer=a.createRenderbuffer(),A(h.__webglDepthRenderbuffer,b,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.");if(r){c.bindTexture(34067,l.__webglTexture);C(34067,b.texture,t);for(q=0;6>q;q++)v(h.__webglFramebuffer[q],b,36064,34069+q);p(b.texture,t)&&u(34067,b.texture,b.width, +b.height);c.bindTexture(34067,null)}else c.bindTexture(3553,l.__webglTexture),C(3553,b.texture,t),v(h.__webglFramebuffer,b,36064,3553),p(b.texture,t)&&u(3553,b.texture,b.width,b.height),c.bindTexture(3553,null);if(b.depthBuffer){h=d.get(b);l=!0===b.isWebGLRenderTargetCube;if(b.depthTexture){if(l)throw Error("target.depthTexture not supported in Cube render targets");if(b&&b.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(36160,h.__webglFramebuffer); +if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&&b.depthTexture.image.width===b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0);w(b.depthTexture,0);h=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(36160,36096,3553,h,0);else if(1027=== +b.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,h,0);else throw Error("Unknown depthTexture format");}else if(l)for(h.__webglDepthbuffer=[],l=0;6>l;l++)a.bindFramebuffer(36160,h.__webglFramebuffer[l]),h.__webglDepthbuffer[l]=a.createRenderbuffer(),A(h.__webglDepthbuffer[l],b);else a.bindFramebuffer(36160,h.__webglFramebuffer),h.__webglDepthbuffer=a.createRenderbuffer(),A(h.__webglDepthbuffer,b);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap=function(a){var b=a.texture, +f=m(a)||e.isWebGL2;if(p(b,f)){f=a.isWebGLRenderTargetCube?34067:3553;var g=d.get(b).__webglTexture;c.bindTexture(f,g);u(f,b,a.width,a.height);c.bindTexture(f,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(e.isWebGL2){var c=d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer);c=b.width;var f=b.height,g=16384;b.depthBuffer&&(g|=256);b.stencilBuffer&&(g|=1024);a.blitFramebuffer(0,0,c,f,0,0,c,f, +g,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===J&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."),J=!0),a=a.texture);w(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLRenderTargetCube&&(!1===F&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."), +F=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?z(a,b):x(a,b)}}function Eh(a,b,c){return{convert:function(a){if(1E3===a)return 10497;if(1001===a)return 33071;if(1002===a)return 33648;if(1003===a)return 9728;if(1004===a)return 9984;if(1005===a)return 9986;if(1006===a)return 9729;if(1007===a)return 9985;if(1008===a)return 9987;if(1009===a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)return 33635;if(1010===a)return 5120;if(1011===a)return 5122; +if(1012===a)return 5123;if(1013===a)return 5124;if(1014===a)return 5125;if(1015===a)return 5126;if(1016===a){if(c.isWebGL2)return 5131;var d=b.get("OES_texture_half_float");if(null!==d)return d.HALF_FLOAT_OES}if(1021===a)return 6406;if(1022===a)return 6407;if(1023===a)return 6408;if(1024===a)return 6409;if(1025===a)return 6410;if(1026===a)return 6402;if(1027===a)return 34041;if(1028===a)return 6403;if(100===a)return 32774;if(101===a)return 32778;if(102===a)return 32779;if(200===a)return 0;if(201=== +a)return 1;if(202===a)return 768;if(203===a)return 769;if(204===a)return 770;if(205===a)return 771;if(206===a)return 772;if(207===a)return 773;if(208===a)return 774;if(209===a)return 775;if(210===a)return 776;if(33776===a||33777===a||33778===a||33779===a)if(d=b.get("WEBGL_compressed_texture_s3tc"),null!==d){if(33776===a)return d.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777===a)return d.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===a)return d.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return d.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(35840=== +a||35841===a||35842===a||35843===a)if(d=b.get("WEBGL_compressed_texture_pvrtc"),null!==d){if(35840===a)return d.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(35841===a)return d.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return d.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return d.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(36196===a&&(d=b.get("WEBGL_compressed_texture_etc1"),null!==d))return d.COMPRESSED_RGB_ETC1_WEBGL;if(37808===a||37809===a||37810===a||37811===a||37812===a||37813===a||37814===a||37815===a||37816=== +a||37817===a||37818===a||37819===a||37820===a||37821===a)if(d=b.get("WEBGL_compressed_texture_astc"),null!==d)return a;if(103===a||104===a){if(c.isWebGL2){if(103===a)return 32775;if(104===a)return 32776}d=b.get("EXT_blend_minmax");if(null!==d){if(103===a)return d.MIN_EXT;if(104===a)return d.MAX_EXT}}if(1020===a){if(c.isWebGL2)return 34042;d=b.get("WEBGL_depth_texture");if(null!==d)return d.UNSIGNED_INT_24_8_WEBGL}return 0}}}function Hc(){B.call(this);this.type="Group"}function Id(a){la.call(this); +this.cameras=a||[]}function Fh(a,b,c){Gh.setFromMatrixPosition(b.matrixWorld);Hh.setFromMatrixPosition(c.matrixWorld);var d=Gh.distanceTo(Hh),e=b.projectionMatrix.elements,f=c.projectionMatrix.elements,g=e[14]/(e[10]-1);c=e[14]/(e[10]+1);var h=(e[9]+1)/e[5],l=(e[9]-1)/e[5],m=(e[8]-1)/e[0],p=(f[8]+1)/f[0];e=g*m;f=g*p;p=d/(-m+p);m=p*-m;b.matrixWorld.decompose(a.position,a.quaternion,a.scale);a.translateX(m);a.translateZ(p);a.matrixWorld.compose(a.position,a.quaternion,a.scale);a.matrixWorldInverse.getInverse(a.matrixWorld); +b=g+p;g=c+p;a.projectionMatrix.makePerspective(e-m,f+(d-m),h*c/g*b,l*c/g*b,b,g)}function cg(a){function b(){return null!==h&&!0===h.isPresenting}function c(){if(b()){var c=h.getEyeParameters("left");e=2*c.renderWidth*q;f=c.renderHeight*q;Fa=a.getPixelRatio();a.getSize(E);a.setDrawingBufferSize(e,f,1);x.viewport.set(0,0,e/2,f);C.viewport.set(e/2,0,e/2,f);B.start();g.dispatchEvent({type:"sessionstart"})}else g.enabled&&a.setDrawingBufferSize(E.width,E.height,Fa),B.stop(),g.dispatchEvent({type:"sessionend"})} +function d(a,b){null!==b&&4===b.length&&a.set(b[0]*e,b[1]*f,b[2]*e,b[3]*f)}var e,f,g=this,h=null,l=null,m=null,p=[],u=new P,k=new P,q=1,t="local-floor";"undefined"!==typeof window&&"VRFrameData"in window&&(l=new window.VRFrameData,window.addEventListener("vrdisplaypresentchange",c,!1));var y=new P,w=new na,z=new n,x=new la;x.viewport=new da;x.layers.enable(1);var C=new la;C.viewport=new da;C.layers.enable(2);var W=new Id([x,C]);W.layers.enable(1);W.layers.enable(2);var E=new v,Fa,A=[];this.enabled= +!1;this.getController=function(a){var b=p[a];void 0===b&&(b=new Hc,b.matrixAutoUpdate=!1,b.visible=!1,p[a]=b);return b};this.getDevice=function(){return h};this.setDevice=function(a){void 0!==a&&(h=a);B.setContext(a)};this.setFramebufferScaleFactor=function(a){q=a};this.setReferenceSpaceType=function(a){t=a};this.setPoseTarget=function(a){void 0!==a&&(m=a)};this.getCamera=function(a){var c="local-floor"===t?1.6:0;if(!1===b())return a.position.set(0,c,0),a.rotation.set(0,0,0),a;h.depthNear=a.near; +h.depthFar=a.far;h.getFrameData(l);if("local-floor"===t){var e=h.stageParameters;e?u.fromArray(e.sittingToStandingTransform):u.makeTranslation(0,c,0)}c=l.pose;e=null!==m?m:a;e.matrix.copy(u);e.matrix.decompose(e.position,e.quaternion,e.scale);null!==c.orientation&&(w.fromArray(c.orientation),e.quaternion.multiply(w));null!==c.position&&(w.setFromRotationMatrix(u),z.fromArray(c.position),z.applyQuaternion(w),e.position.add(z));e.updateMatrixWorld();x.near=a.near;C.near=a.near;x.far=a.far;C.far=a.far; +x.matrixWorldInverse.fromArray(l.leftViewMatrix);C.matrixWorldInverse.fromArray(l.rightViewMatrix);k.getInverse(u);"local-floor"===t&&(x.matrixWorldInverse.multiply(k),C.matrixWorldInverse.multiply(k));a=e.parent;null!==a&&(y.getInverse(a.matrixWorld),x.matrixWorldInverse.multiply(y),C.matrixWorldInverse.multiply(y));x.matrixWorld.getInverse(x.matrixWorldInverse);C.matrixWorld.getInverse(C.matrixWorldInverse);x.projectionMatrix.fromArray(l.leftProjectionMatrix);C.projectionMatrix.fromArray(l.rightProjectionMatrix); +Fh(W,x,C);a=h.getLayers();a.length&&(a=a[0],d(x.viewport,a.leftBounds),d(C.viewport,a.rightBounds));a:for(a=0;af.matrixWorld.determinant();ha.setMaterial(e,h);var l=r(a,c,e,f),m=!1;if(b!==d.id||Y!==l.id||ba!==(!0===e.wireframe))b=d.id,Y=l.id,ba=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(xa.update(f,d,e,l), +m=!0);h=d.index;var p=d.attributes.position;c=1;!0===e.wireframe&&(h=wa.getWireframeAttribute(d),c=2);a=za;if(null!==h){var k=ua.get(h);a=Ba;a.setIndex(k)}if(m){if(d&&d.isInstancedBufferGeometry&&!Ea.isWebGL2&&null===oa.get("ANGLE_instanced_arrays"))console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");else{ha.initAttributes();m=d.attributes;l=l.getAttributes();var u=e.defaultAttributeValues; +for(v in l){var q=l[v];if(0<=q){var t=m[v];if(void 0!==t){var n=t.normalized,y=t.itemSize,w=ua.get(t);if(void 0!==w){var x=w.buffer,z=w.type;w=w.bytesPerElement;if(t.isInterleavedBufferAttribute){var C=t.data,E=C.stride;t=t.offset;C&&C.isInstancedInterleavedBuffer?(ha.enableAttributeAndDivisor(q,C.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=C.meshPerAttribute*C.count)):ha.enableAttribute(q);M.bindBuffer(34962,x);M.vertexAttribPointer(q,y,z,n,E*w,t*w)}else t.isInstancedBufferAttribute? +(ha.enableAttributeAndDivisor(q,t.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=t.meshPerAttribute*t.count)):ha.enableAttribute(q),M.bindBuffer(34962,x),M.vertexAttribPointer(q,y,z,n,0,0)}}else if(void 0!==u&&(n=u[v],void 0!==n))switch(n.length){case 2:M.vertexAttrib2fv(q,n);break;case 3:M.vertexAttrib3fv(q,n);break;case 4:M.vertexAttrib4fv(q,n);break;default:M.vertexAttrib1fv(q,n)}}}ha.disableUnusedAttributes()}null!==h&&M.bindBuffer(34963,k.buffer)}k=Infinity;null!==h?k=h.count: +void 0!==p&&(k=p.count);h=d.drawRange.start*c;p=null!==g?g.start*c:0;var v=Math.max(h,p);g=Math.max(0,Math.min(k,h+d.drawRange.count*c,p+(null!==g?g.count*c:Infinity))-1-v+1);if(0!==g){if(f.isMesh)if(!0===e.wireframe)ha.setLineWidth(e.wireframeLinewidth*(null===K?fa:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),ha.setLineWidth(e*(null===K?fa:1)),f.isLineSegments?a.setMode(1):f.isLineLoop? +a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);d&&d.isInstancedBufferGeometry?0e.far||f.push({distance:a,distanceToRay:Math.sqrt(h), +point:c,index:b,face:null,object:g}))}function hg(a,b,c,d,e,f,g,h,l){ba.call(this,a,b,c,d,e,f,g,h,l);this.format=void 0!==g?g:1022;this.minFilter=void 0!==f?f:1006;this.magFilter=void 0!==e?e:1006;this.generateMipmaps=!1}function Lc(a,b,c,d,e,f,g,h,l,m,p,k){ba.call(this,null,f,g,h,l,m,d,e,p,k);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1}function Od(a,b,c,d,e,f,g,h,l){ba.call(this,a,b,c,d,e,f,g,h,l);this.needsUpdate=!0}function Pd(a,b,c,d,e,f,g,h,l,m){m=void 0!== +m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===c&&1026===m&&(c=1012);void 0===c&&1027===m&&(c=1020);ba.call(this,null,d,e,f,g,h,m,c,l);this.image={width:a,height:b};this.magFilter=void 0!==g?g:1003;this.minFilter=void 0!==h?h:1003;this.generateMipmaps=this.flipY=!1}function Mc(a){D.call(this);this.type="WireframeGeometry";var b=[],c,d,e,f=[0,0],g={},h=["a","b","c"];if(a&&a.isGeometry){var l=a.faces;var m=0;for(d= +l.length;mc;c++){var k=p[h[c]];var r=p[h[(c+1)%3]];f[0]=Math.min(k,r);f[1]=Math.max(k,r);k=f[0]+","+f[1];void 0===g[k]&&(g[k]={index1:f[0],index2:f[1]})}}for(k in g)m=g[k],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new n,null!==a.index){l=a.attributes.position;p=a.index;var q=a.groups;0===q.length&&(q=[{start:0,count:p.count,materialIndex:0}]);a=0;for(e=q.length;ac;c++)k=p.getX(m+c),r=p.getX(m+(c+1)%3),f[0]=Math.min(k,r),f[1]=Math.max(k,r),k=f[0]+","+f[1],void 0===g[k]&&(g[k]={index1:f[0],index2:f[1]});for(k in g)m=g[k],h.fromBufferAttribute(l,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(l,m.index2),b.push(h.x,h.y,h.z)}else for(l=a.attributes.position,m=0,d=l.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z);this.addAttribute("position", +new A(b,3))}function Qd(a,b,c){G.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Nc(a,b,c));this.mergeVertices()}function Nc(a,b,c){D.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,l=new n,m=new n,p=new n,k=new n,r,q;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.");var t=b+1;for(r=0;r<=c;r++){var y= +r/c;for(q=0;q<=b;q++){var w=q/b;a(w,y,l);e.push(l.x,l.y,l.z);0<=w-1E-5?(a(w-1E-5,y,m),p.subVectors(l,m)):(a(w+1E-5,y,m),p.subVectors(m,l));0<=y-1E-5?(a(w,y-1E-5,m),k.subVectors(l,m)):(a(w,y+1E-5,m),k.subVectors(m,l));h.crossVectors(p,k).normalize();f.push(h.x,h.y,h.z);g.push(w,y)}}for(r=0;rd&&1===a.x&&(l[b]=a.x-1);0===c.x&&0===c.z&&(l[b]=d/2/Math.PI+.5)}D.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c= +c||1;d=d||0;var h=[],l=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(l[a+0]+=1),.2>c&&(l[a+2]+=1),.2>d&&(l[a+4]+=1))})();this.addAttribute("position",new A(h,3));this.addAttribute("normal",new A(h.slice(),3));this.addAttribute("uv",new A(l,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Sd(a,b){G.call(this); +this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Oc(a,b));this.mergeVertices()}function Oc(a,b){pa.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Td(a,b){G.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new bc(a,b));this.mergeVertices()}function bc(a,b){pa.call(this,[1,0,0,-1,0,0,0,1,0,0,-1, +0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Ud(a,b){G.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Pc(a,b));this.mergeVertices()}function Pc(a,b){var c=(1+Math.sqrt(5))/2;pa.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7, +6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Vd(a,b){G.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Qc(a,b));this.mergeVertices()}function Qc(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;pa.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c, +0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Wd(a,b,c,d,e,f){G.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};void 0!== +f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new cc(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function cc(a,b,c,d,e){function f(e){p=a.getPointAt(e/b,p);var f=g.normals[e];e=g.binormals[e];for(r=0;r<=d;r++){var m=r/d*Math.PI*2,k=Math.sin(m);m=-Math.cos(m);l.x=m*f.x+k*e.x;l.y=m*f.y+k*e.y;l.z=m*f.z+k*e.z;l.normalize();t.push(l.x,l.y,l.z);h.x=p.x+c*l.x;h.y=p.y+c*l.y;h.z=p.z+c*l.z;q.push(h.x, +h.y,h.z)}}D.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,l=new n,m=new v,p=new n,k,r,q=[],t=[],y=[],w=[];for(k=0;k=b;e-=d)f=Mh(e,a[e],a[e+1],f);f&&dc(f,f.next)&&(Zd(f),f=f.next);return f}function $d(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!dc(a,a.next)&&0!==ua(a.prev,a,a.next))a=a.next;else{Zd(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b} +function ae(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,l=h;do null===l.z&&(l.z=ig(l.x,l.y,d,e,f)),l.prevZ=l.prev,l=l.nextZ=l.next;while(l!==h);l.prevZ.nextZ=null;l.prevZ=null;h=l;var m,p,k,r,q=1;do{l=h;var t=h=null;for(p=0;l;){p++;var n=l;for(m=k=0;mn!==t.next.y>n&&t.next.y!==t.y&&k<(t.next.x-t.x)*(n-t.y)/(t.next.y-t.y)+t.x&&(p=!p),t=t.next;while(t!==l);t=p}l=t}if(l){a=Oh(g,h);g=$d(g,g.next);a=$d(a,a.next);ae(g,b,c,d,e,f);ae(a,b,c,d,e,f);break a}h= +h.next}g=g.next}while(g!==a)}break}}}}function ak(a,b,c,d){var e=a.prev,f=a.next;if(0<=ua(e,a,f))return!1;var g=e.x>a.x?e.x>f.x?e.x:f.x:a.x>f.x?a.x:f.x,h=e.y>a.y?e.y>f.y?e.y:f.y:a.y>f.y?a.y:f.y,l=ig(e.x=l&&d&&d.z<=b;){if(c!==a.prev&&c!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=ua(c.prev,c,c.next))return!1;c=c.prevZ;if(d!==a.prev&&d!==a.next&&Tc(e.x,e.y,a.x,a.y, +f.x,f.y,d.x,d.y)&&0<=ua(d.prev,d,d.next))return!1;d=d.nextZ}for(;c&&c.z>=l;){if(c!==a.prev&&c!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=ua(c.prev,c,c.next))return!1;c=c.prevZ}for(;d&&d.z<=b;){if(d!==a.prev&&d!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=ua(d.prev,d,d.next))return!1;d=d.nextZ}return!0}function bk(a,b){return a.x-b.x}function ck(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f= +g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&Tc(eh.x)&&be(c,a)&&(h=c,m=p)}c=c.next}return h}function ig(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b| +b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function dk(a){var b=a,c=a;do{if(b.xua(a.prev,a,a.next)?0<=ua(a,b,a.next)&&0<=ua(a,a.prev,b):0>ua(a,b,a.prev)||0>ua(a,a.next,b)}function Oh(a,b){var c=new jg(a.i,a.x,a.y),d=new jg(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function Mh(a,b,c,d){a=new jg(a,b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function Zd(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ= +a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function jg(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function Ph(a){var b=a.length;2Number.EPSILON){var l=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/l;b=b.y+d/l;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new v(f,d);e=Math.sqrt(e/2)}else a=!1,d>Number.EPSILON?f>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)=== +Math.sign(g)&&(a=!0),a?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new v(f/e,d/e)}function h(a,b){for(L=a.length;0<=--L;){var c=L;var f=L-1;0>f&&(f=a.length-1);var g,h=x+2*D;for(g=0;gk;k++){var n=m[f[k]];var r=m[f[(k+1)%3]];d[0]=Math.min(n,r);d[1]=Math.max(n,r);n=d[0]+","+d[1];void 0===e[n]?e[n]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[n].face2=h}for(n in e)if(d=e[n],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new A(c,3))}function hc(a,b,c,d,e,f,g,h){G.call(this);this.type="CylinderGeometry"; +this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new rb(a,b,c,d,e,f,g,h));this.mergeVertices()}function rb(a,b,c,d,e,f,g,h){function l(c){var e,f=new v,l=new n,p=0,y=!0===c?a:b,x=!0===c?1:-1;var A=t;for(e=1;e<=d;e++)u.push(0,w*x,0),r.push(0,x,0),q.push(.5,.5),t++;var B=t;for(e=0;e<=d;e++){var D=e/d*h+g,F=Math.cos(D);D=Math.sin(D);l.x=y*D;l.y=w*x;l.z=y*F;u.push(l.x,l.y,l.z);r.push(0,x,0);f.x=.5*F+ +.5;f.y=.5*D*x+.5;q.push(f.x,f.y);t++}for(e=0;ethis.duration&&this.resetDuration()}function fk(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return $c;case "vector":case "vector2":case "vector3":case "vector4":return ad; +case "color":return Re;case "quaternion":return ke;case "bool":case "boolean":return Qe;case "string":return Te}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function gk(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=fk(a.type);if(void 0===a.times){var c=[],d=[];Z.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)}function kg(a,b,c){var d=this,e= +!1,f=0,g=0,h=void 0;this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()};this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this}}function aa(a){this.manager=void 0!==a?a:Th;this.crossOrigin= +"anonymous";this.resourcePath=this.path=""}function Na(a){aa.call(this,a)}function lg(a){aa.call(this,a)}function mg(a){aa.call(this,a);this._parser=null}function Ue(a){aa.call(this,a);this._parser=null}function bd(a){aa.call(this,a)}function Ve(a){aa.call(this,a)}function We(a){aa.call(this,a)}function F(){this.type="Curve";this.arcLengthDivisions=200}function Ia(a,b,c,d,e,f,g,h){F.call(this);this.type="EllipseCurve";this.aX=a||0;this.aY=b||0;this.xRadius=c||1;this.yRadius=d||1;this.aStartAngle= +e||0;this.aEndAngle=f||2*Math.PI;this.aClockwise=g||!1;this.aRotation=h||0}function cd(a,b,c,d,e,f){Ia.call(this,a,b,c,c,d,e,f);this.type="ArcCurve"}function ng(){var a=0,b=0,c=0,d=0;return{initCatmullRom:function(e,f,g,h,l){e=l*(g-e);h=l*(h-f);a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},initNonuniformCatmullRom:function(e,f,g,h,l,m,k){e=((f-e)/l-(g-e)/(l+m)+(g-f)/m)*m;h=((g-f)/m-(h-f)/(m+k)+(h-g)/k)*m;a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},calc:function(e){var f=e*e;return a+b*e+c*f+d*f*e}}}function sa(a, +b,c,d){F.call(this);this.type="CatmullRomCurve3";this.points=a||[];this.closed=b||!1;this.curveType=c||"centripetal";this.tension=d||.5}function Uh(a,b,c,d,e){b=.5*(d-b);e=.5*(e-c);var f=a*a;return(2*c-2*d+b+e)*a*f+(-3*c+3*d-2*b-e)*f+b*a+c}function le(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}function me(a,b,c,d,e){var f=1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}function Sa(a,b,c,d){F.call(this);this.type="CubicBezierCurve";this.v0=a||new v;this.v1=b||new v;this.v2=c||new v; +this.v3=d||new v}function gb(a,b,c,d){F.call(this);this.type="CubicBezierCurve3";this.v0=a||new n;this.v1=b||new n;this.v2=c||new n;this.v3=d||new n}function Da(a,b){F.call(this);this.type="LineCurve";this.v1=a||new v;this.v2=b||new v}function Ta(a,b){F.call(this);this.type="LineCurve3";this.v1=a||new n;this.v2=b||new n}function Ua(a,b,c){F.call(this);this.type="QuadraticBezierCurve";this.v0=a||new v;this.v1=b||new v;this.v2=c||new v}function hb(a,b,c){F.call(this);this.type="QuadraticBezierCurve3"; +this.v0=a||new n;this.v1=b||new n;this.v2=c||new n}function Va(a){F.call(this);this.type="SplineCurve";this.points=a||[]}function sb(){F.call(this);this.type="CurvePath";this.curves=[];this.autoClose=!1}function Wa(a){sb.call(this);this.type="Path";this.currentPoint=new v;a&&this.setFromPoints(a)}function Jb(a){Wa.call(this,a);this.uuid=O.generateUUID();this.type="Shape";this.holes=[]}function V(a,b){B.call(this);this.type="Light";this.color=new J(a);this.intensity=void 0!==b?b:1;this.receiveShadow= +void 0}function Xe(a,b,c){V.call(this,a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(B.DefaultUp);this.updateMatrix();this.groundColor=new J(b)}function ib(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new v(512,512);this.mapPass=this.map=null;this.matrix=new P;this._frustum=new Ed;this._frameExtents=new v(1,1);this._viewportCount=1;this._viewports=[new da(0,0,1,1)]}function Ye(){ib.call(this,new la(50,1,.5,500))}function Ze(a,b,c,d,e,f){V.call(this,a,b);this.type= +"SpotLight";this.position.copy(B.DefaultUp);this.updateMatrix();this.target=new B;Object.defineProperty(this,"power",{get:function(){return this.intensity*Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Ye}function og(){ib.call(this,new la(90,1,.5,500));this._frameExtents=new v(4,2);this._viewportCount=6;this._viewports=[new da(2,1,1,1),new da(0,1,1,1),new da(3, +1,1,1),new da(1,1,1,1),new da(3,0,1,1),new da(1,0,1,1)];this._cubeDirections=[new n(1,0,0),new n(-1,0,0),new n(0,0,1),new n(0,0,-1),new n(0,1,0),new n(0,-1,0)];this._cubeUps=[new n(0,1,0),new n(0,1,0),new n(0,1,0),new n(0,1,0),new n(0,0,1),new n(0,0,-1)]}function $e(a,b,c,d){V.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",{get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d: +1;this.shadow=new og}function ne(a,b,c,d,e,f){bb.call(this);this.type="OrthographicCamera";this.zoom=1;this.view=null;this.left=void 0!==a?a:-1;this.right=void 0!==b?b:1;this.top=void 0!==c?c:1;this.bottom=void 0!==d?d:-1;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()}function af(){ib.call(this,new ne(-5,5,5,-5,.5,500))}function bf(a,b){V.call(this,a,b);this.type="DirectionalLight";this.position.copy(B.DefaultUp);this.updateMatrix();this.target=new B;this.shadow= +new af}function cf(a,b){V.call(this,a,b);this.type="AmbientLight";this.castShadow=void 0}function df(a,b,c,d){V.call(this,a,b);this.type="RectAreaLight";this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function ef(a){aa.call(this,a);this.textures={}}function ff(){D.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function gf(a,b,c,d){"number"===typeof c&&(d=c,c=!1,console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.")); +N.call(this,a,b,c);this.meshPerAttribute=d||1}function hf(a){aa.call(this,a)}function jf(a){aa.call(this,a)}function pg(a){"undefined"===typeof createImageBitmap&&console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported.");"undefined"===typeof fetch&&console.warn("THREE.ImageBitmapLoader: fetch() not supported.");aa.call(this,a);this.options=void 0}function qg(){this.type="ShapePath";this.color=new J;this.subPaths=[];this.currentPath=null}function rg(a){this.type="Font";this.data= +a}function sg(a){aa.call(this,a)}function kf(a){aa.call(this,a)}function lf(){this.coefficients=[];for(var a=0;9>a;a++)this.coefficients.push(new n)}function Xa(a,b){V.call(this,void 0,b);this.sh=void 0!==a?a:new lf}function tg(a,b,c){Xa.call(this,void 0,c);a=(new J).set(a);c=(new J).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c);this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)}function ug(a, +b){Xa.call(this,void 0,b);a=(new J).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))}function Vh(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new la;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new la;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1;this._cache={focus:null,fov:null,aspect:null,near:null,far:null,zoom:null,eyeSep:null}}function vg(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime= +this.oldTime=this.startTime=0;this.running=!1}function wg(){B.call(this);this.type="AudioListener";this.context=xg.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0;this._clock=new vg}function dd(a){B.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.startTime= +0;this.duration=void 0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}function yg(a){dd.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function zg(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function Ag(a,b,c){this.binding=a;this.valueSize= +c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function Wh(a,b,c){c=c||ma.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function ma(a,b,c){this.path=b;this.parsedPath=c||ma.parseTrackName(b);this.node=ma.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Xh(){this.uuid= +O.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var a={};this._indicesByUUID=a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function Yh(a,b,c){this._mixer=a;this._clip=b;this._localRoot= +c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity; +this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function Bg(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function mf(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Cg(a,b,c){ac.call(this,a,b);this.meshPerAttribute=c||1}function Zh(a,b,c,d){this.ray=new Sb(a,b);this.near=c||0;this.far=d||Infinity;this.camera=null;this.params={Mesh:{}, +Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");return this.Points}}})}function $h(a,b){return a.distance-b.distance}function Dg(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1, +Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new A(b,3));b=new Y({fog:!1});this.cone=new R(a,b);this.add(this.cone);this.update()}function ci(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;ca?-1:0ve;ve++)qa[ve]=(16>ve?"0":"")+ +ve.toString(16);var O={DEG2RAD:Math.PI/180,RAD2DEG:180/Math.PI,generateUUID:function(){var a=4294967295*Math.random()|0,b=4294967295*Math.random()|0,c=4294967295*Math.random()|0,d=4294967295*Math.random()|0;return(qa[a&255]+qa[a>>8&255]+qa[a>>16&255]+qa[a>>24&255]+"-"+qa[b&255]+qa[b>>8&255]+"-"+qa[b>>16&15|64]+qa[b>>24&255]+"-"+qa[c&63|128]+qa[c>>8&255]+"-"+qa[c>>16&255]+qa[c>>24&255]+qa[d&255]+qa[d>>8&255]+qa[d>>16&255]+qa[d>>24&255]).toUpperCase()},clamp:function(a,b,c){return Math.max(b,Math.min(c, +a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},lerp:function(a,b,c){return(1-c)*a+c*b},smoothstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a* +(.5-Math.random())},degToRad:function(a){return a*O.DEG2RAD},radToDeg:function(a){return a*O.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(v.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(v.prototype, +{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x, +this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y= +a[1]*b+a[4]*c+a[7];return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c|| +1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x* +a.x+this.y*a.y},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b= +this.x-a.x;a=this.y-a.y;return b*b+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a, +b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(na,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h= +c[d+0],l=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var k=e[f+1],n=e[f+2];e=e[f+3];if(c!==e||h!==d||l!==k||m!==n){f=1-g;var r=h*d+l*k+m*n+c*e,q=0<=r?1:-1,t=1-r*r;t>Number.EPSILON&&(t=Math.sqrt(t),r=Math.atan2(t,r*q),f=Math.sin(f*r)/t,g=Math.sin(g*r)/t);q*=g;h=h*f+d*q;l=l*f+k*q;m=m*f+n*q;c=c*f+e*q;f===1-g&&(g=1/Math.sqrt(h*h+l*l+m*m+c*c),h*=g,l*=g,m*=g,c*=g)}a[b]=h;a[b+1]=l;a[b+2]=m;a[b+3]=c}});Object.defineProperties(na.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}}, +y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this._onChangeCallback()}}});Object.assign(na.prototype,{isQuaternion:!0,set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x= +a.x;this._y=a.y;this._z=a.z;this._w=a.w;this._onChangeCallback();return this},setFromEuler:function(a,b){if(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),l=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"YXZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z= +h*l*e-c*d*f,this._w=h*l*f+c*d*e):"ZXY"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"ZYX"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f+c*d*e):"YZX"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f-c*d*e):"XZY"===a&&(this._x=c*l*f-h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f+c*d*e);!1!==b&&this._onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b); +this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);this._onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],l=b[6];b=b[10];var m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(l-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+l)/ +c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+l)/c,this._z=.25*c);this._onChangeCallback();return this},setFromUnitVectors:function(a,b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z=a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(O.clamp(this.dot(a),-1,1)))},rotateTowards:function(a, +b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this._onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a= +this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this._onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w; +var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;this._onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g* +f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize(),this._onChangeCallback(),this;a=Math.sqrt(a);var h=Math.atan2(a,g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this._onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2]; +this._w=a[b+3];this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});var Ig=new n,fi=new na;Object.assign(n.prototype,{isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y= +a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this}, +add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*= +a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(a){a&&a.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(fi.setFromEuler(a))},applyAxisAngle:function(a,b){return this.applyQuaternion(fi.setFromAxisAngle(a,b))},applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]* +d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,l=a*c+g*b-e*d,m=a*d+e*c-f*b;b=-e*b-f*c-g*d;this.x=h*a+b*-e+l*-g-m*-f;this.y=l*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-l*-e;return this}, +project:function(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)},unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/ +a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a, +Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x= +0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+ +Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this, +a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(a){Ig.copy(this).projectOnVector(a);return this.sub(Ig)},reflect:function(a){return this.sub(Ig.copy(a).multiplyScalar(2*this.dot(a)))},angleTo:function(a){a=this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(O.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))}, +distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)*a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta, +a.y)},setFromCylindricalCoords:function(a,b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,4*b)},equals:function(a){return a.x=== +this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});var pc=new n;Object.assign(ta.prototype,{isMatrix3:!0,set:function(a, +b,c,d,e,f,g,h,l){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=l;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this}, +applyToBufferAttribute:function(a){for(var b=0,c=a.count;bc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];return a}});var Dc,ub={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===Dc&&(Dc=document.createElementNS("http://www.w3.org/1999/xhtml", -"canvas"));Dc.width=a.width;Dc.height=a.height;var b=Dc.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=Dc}return 2048c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];return a}});var md,Kb={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===md&&(md=document.createElementNS("http://www.w3.org/1999/xhtml", +"canvas"));md.width=a.width;md.height=a.height;var b=md.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=md}return 2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(Y.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.defineProperties(ea.prototype,{width:{get:function(){return this.z},set:function(a){this.z=a}},height:{get:function(){return this.w},set:function(a){this.w=a}}});Object.assign(ea.prototype,{isVector4:!0,set:function(a,b,c,d){this.x= +g;f++)e.push(Kb.getDataURL(d[f]))}else e=Kb.getDataURL(d);a.images[d.uuid]={uuid:d.uuid,url:e}}c.image=d.uuid}b||(a.textures[this.uuid]=c);return c},dispose:function(){this.dispatchEvent({type:"dispose"})},transformUv:function(a){if(300!==this.mapping)return a;a.applyMatrix3(this.matrix);if(0>a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(ba.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.defineProperties(da.prototype,{width:{get:function(){return this.z},set:function(a){this.z=a}},height:{get:function(){return this.w},set:function(a){this.w=a}}});Object.assign(da.prototype,{isVector4:!0,set:function(a,b,c,d){this.x= a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x; case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z,this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this}, addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-= a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/ -a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var h=a[2];var k=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-h)&&.01>Math.abs(g-k)){if(.1>Math.abs(c+e)&&.1>Math.abs(d+h)&&.1>Math.abs(g+k)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI; -b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+h)/4;g=(g+k)/4;b>f&&b>m?.01>b?(k=0,c=h=.707106781):(k=Math.sqrt(b),h=c/k,c=d/k):f>m?.01>f?(k=.707106781,h=0,c=.707106781):(h=Math.sqrt(f),k=c/h,c=g/h):.01>m?(h=k=.707106781,c=0):(c=Math.sqrt(m),k=d/c,h=g/c);this.set(k,h,c,a);return this}a=Math.sqrt((k-g)*(k-g)+(d-h)*(d-h)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(k-g)/a;this.y=(d-h)/a;this.z=(e-c)/a;this.w=Math.acos((b+f+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y, +a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var h=a[2];var l=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-h)&&.01>Math.abs(g-l)){if(.1>Math.abs(c+e)&&.1>Math.abs(d+h)&&.1>Math.abs(g+l)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI; +b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+h)/4;g=(g+l)/4;b>f&&b>m?.01>b?(l=0,c=h=.707106781):(l=Math.sqrt(b),h=c/l,c=d/l):f>m?.01>f?(l=.707106781,h=0,c=.707106781):(h=Math.sqrt(f),l=c/h,c=g/h):.01>m?(h=l=.707106781,c=0):(c=Math.sqrt(m),l=d/c,h=g/c);this.set(l,h,c,a);return this}a=Math.sqrt((l-g)*(l-g)+(d-h)*(d-h)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(l-g)/a;this.y=(d-h)/a;this.z=(e-c)/a;this.w=Math.acos((b+f+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y, a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));this.w=Math.max(a.w,Math.min(b.w,this.w));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b, this.y));this.z=Math.max(a,Math.min(b,this.z));this.w=Math.max(a,Math.min(b,this.w));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x= Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z* a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z- this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute()."); -this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});Va.prototype=Object.assign(Object.create(na.prototype),{constructor:Va,isWebGLRenderTarget:!0,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.texture.image.width=a,this.texture.image.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport); -this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});ne.prototype=Object.assign(Object.create(Va.prototype),{constructor:ne,isWebGLMultisampleRenderTarget:!0,copy:function(a){Va.prototype.copy.call(this,a);this.samples=a.samples;return this}});Object.assign(Q.prototype,{isMatrix4:!0,set:function(a,b,c,d,e,f,g,h,k,m,l,p,n,t,q,v){var r=this.elements;r[0]= -a;r[4]=b;r[8]=c;r[12]=d;r[1]=e;r[5]=f;r[9]=g;r[13]=h;r[2]=k;r[6]=m;r[10]=l;r[14]=p;r[3]=n;r[7]=t;r[11]=q;r[15]=v;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new Q).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return this},copyPosition:function(a){var b= -this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a,b,c){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(){var a=new n;return function(b){var c=this.elements,d=b.elements,e=1/a.setFromMatrixColumn(b,0).length(),f=1/a.setFromMatrixColumn(b,1).length();b=1/a.setFromMatrixColumn(b, -2).length();c[0]=d[0]*e;c[1]=d[1]*e;c[2]=d[2]*e;c[3]=0;c[4]=d[4]*f;c[5]=d[5]*f;c[6]=d[6]*f;c[7]=0;c[8]=d[8]*b;c[9]=d[9]*b;c[10]=d[10]*b;c[11]=0;c[12]=0;c[13]=0;c[14]=0;c[15]=1;return this}}(),makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c);c=Math.sin(c);var g=Math.cos(d);d=Math.sin(d);var h=Math.cos(e);e=Math.sin(e);if("XYZ"===a.order){a= -f*h;var k=f*e,m=c*h,l=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=k+m*d;b[5]=a-l*d;b[9]=-c*g;b[2]=l-a*d;b[6]=m+k*d;b[10]=f*g}else"YXZ"===a.order?(a=g*h,k=g*e,m=d*h,l=d*e,b[0]=a+l*c,b[4]=m*c-k,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=k*c-m,b[6]=l+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,k=g*e,m=d*h,l=d*e,b[0]=a-l*c,b[4]=-f*e,b[8]=m+k*c,b[1]=k+m*c,b[5]=f*h,b[9]=l-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,k=f*e,m=c*h,l=c*e,b[0]=g*h,b[4]=m*d-k,b[8]=a*d+l,b[1]=g*e,b[5]=l*d+a,b[9]=k*d-m,b[2]=-d,b[6]=c* -g,b[10]=f*g):"YZX"===a.order?(a=f*g,k=f*d,m=c*g,l=c*d,b[0]=g*h,b[4]=l-a*e,b[8]=m*e+k,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=k*e+m,b[10]=a-l*e):"XZY"===a.order&&(a=f*g,k=f*d,m=c*g,l=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+l,b[5]=f*h,b[9]=k*e-m,b[2]=m*e-k,b[6]=c*h,b[10]=l*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromQuaternion:function(){var a=new n(0,0,0),b=new n(1,1,1);return function(c){return this.compose(a,c,b)}}(),lookAt:function(){var a=new n,b=new n, -c=new n;return function(d,e,f){var g=this.elements;c.subVectors(d,e);0===c.lengthSq()&&(c.z=1);c.normalize();a.crossVectors(f,c);0===a.lengthSq()&&(1===Math.abs(f.z)?c.x+=1E-4:c.z+=1E-4,c.normalize(),a.crossVectors(f,c));a.normalize();b.crossVectors(c,a);g[0]=a.x;g[4]=b.x;g[8]=c.x;g[1]=a.y;g[5]=b.y;g[9]=c.y;g[2]=a.z;g[6]=b.z;g[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."), -this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements;a=c[0];var e=c[4],f=c[8],g=c[12],h=c[1],k=c[5],m=c[9],l=c[13],p=c[2],n=c[6],t=c[10],q=c[14],v=c[3],x=c[7],A=c[11];c=c[15];var w=d[0],y=d[4],z=d[8],H=d[12],D=d[1],B=d[5],F=d[9],E=d[13],C=d[2],G=d[6],I=d[10],J=d[14],M=d[3],N=d[7],T=d[11];d=d[15];b[0]=a*w+e*D+f*C+g*M;b[4]=a*y+e*B+f*G+g*N;b[8]=a*z+e*F+f*I+ -g*T;b[12]=a*H+e*E+f*J+g*d;b[1]=h*w+k*D+m*C+l*M;b[5]=h*y+k*B+m*G+l*N;b[9]=h*z+k*F+m*I+l*T;b[13]=h*H+k*E+m*J+l*d;b[2]=p*w+n*D+t*C+q*M;b[6]=p*y+n*B+t*G+q*N;b[10]=p*z+n*F+t*I+q*T;b[14]=p*H+n*E+t*J+q*d;b[3]=v*w+x*D+A*C+c*M;b[7]=v*y+x*B+A*G+c*N;b[11]=v*z+x*F+A*I+c*T;b[15]=v*H+x*E+A*J+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},applyToBufferAttribute:function(){var a= -new n;return function(b){for(var c=0,d=b.count;cthis.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.copy(this);c=1/g;f=1/h;var m=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=m;b.elements[9]*=m;b.elements[10]*=m;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); -var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),k=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*k;g[9]=0;g[13]=-((c+d)*k);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements; -a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}});var ie,je;vb.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" "); -vb.DefaultOrder="XYZ";Object.defineProperties(vb.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;this._onChangeCallback()}}});Object.assign(vb.prototype,{isEuler:!0,set:function(a,b,c,d){this._x=a;this._y= -b;this._z=c;this._order=d||this._order;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this._onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=O.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],m=e[9],l=e[2],p=e[6];e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-m, -e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(p,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.99999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,k)):(this._y=Math.atan2(-l,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(-l,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(l,-1,1)),.99999>Math.abs(l)?(this._x=Math.atan2(p,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f, -k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-m,k),this._y=Math.atan2(-l,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(p,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;!1!==c&&this._onChangeCallback();return this},setFromQuaternion:function(a,b,c){void 0===ie&&(ie=new Q); -ie.makeRotationFromQuaternion(a);return this.setFromRotationMatrix(ie,b,c)},setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(a){void 0===je&&(je=new da);je.setFromEuler(this);return this.setFromQuaternion(je,a)},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this._onChangeCallback();return this},toArray:function(a, -b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new n(this._x,this._y,this._z)},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});Object.assign(oe.prototype,{set:function(a){this.mask=1<e&&(e=m);l>f&&(f=l);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.count;he&&(e=m);l>f&&(f=l);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<= -this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z? -!1:!0},intersectsSphere:function(){var a=new n;return function(b){this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<=b.radius*b.radius}}(),intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(){function a(a){var e;var f=0;for(e=a.length-3;f<=e;f+=3){h.fromArray(a,f);var g=m.x*Math.abs(h.x)+m.y*Math.abs(h.y)+m.z*Math.abs(h.z),k=b.dot(h),l=c.dot(h),r=d.dot(h);if(Math.max(-Math.max(k,l,r),Math.min(k,l,r))>g)return!1}return!0}var b=new n,c=new n,d=new n,e=new n,f=new n,g=new n,h=new n,k=new n,m=new n,l=new n;return function(h){if(this.isEmpty())return!1;this.getCenter(k);m.subVectors(this.max, -k);b.subVectors(h.a,k);c.subVectors(h.b,k);d.subVectors(h.c,k);e.subVectors(c,b);f.subVectors(d,c);g.subVectors(b,d);h=[0,-e.z,e.y,0,-f.z,f.y,0,-g.z,g.y,e.z,0,-e.x,f.z,0,-f.x,g.z,0,-g.x,-e.y,e.x,0,-f.y,f.x,0,-g.y,g.x,0];if(!a(h))return!1;h=[1,0,0,0,1,0,0,0,1];if(!a(h))return!1;l.crossVectors(e,f);h=[l.x,l.y,l.z];return a(h)}}(),clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"),b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a= -new n;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new n;return function(b){void 0===b&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(b.center);b.radius=.5*this.getSize(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a= -[new n,new n,new n,new n,new n,new n,new n,new n];return function(b){if(this.isEmpty())return this;a[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b); -a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var $e;Object.assign(Wa.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(a,b){void 0===$e&&($e=new Ja);var c=this.center;void 0!==b?c.copy(b):$e.setFromPoints(a).getCenter(c);for(var d=b=0,e=a.length;d=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<= -b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a);void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"), -a=new Ja);a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}});Object.assign(wb.prototype,{set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin); -this.direction.copy(a.direction);return this},at:function(a,b){void 0===b&&(console.warn("THREE.Ray: .at() target is now required"),b=new n);return b.copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(){var a=new n;return function(b){this.origin.copy(this.at(b,a));return this}}(),closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Ray: .closestPointToPoint() target is now required"), -b=new n);b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new n;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceToSquared(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceToSquared(b)}}(),distanceSqToSegment:function(){var a= -new n,b=new n,c=new n;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5);b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var h=.5*d.distanceTo(e),k=-this.direction.dot(b),m=c.dot(this.direction),l=-c.dot(b),p=c.lengthSq(),n=Math.abs(1-k*k);if(0=-t?e<=t?(h=1/n,d*=h,e*=h,k=d*(d+k*e+2*m)+e*(k*d+e+2*l)+p):(e=h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+p):(e=-h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+p):e<=-t?(d=Math.max(0,-(-k*h+m)),e=0b)return null; -b=Math.sqrt(b-e);e=d-b;d+=b;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){a=this.distanceToPlane(a);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin); -return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y-f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null; -if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(){var a=new n;return function(b){return null!==this.intersectBox(b,a)}}(),intersectTriangle:function(){var a=new n,b=new n,c=new n,d=new n;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0f)h=-1,f=-f;else return null;a.subVectors(this.origin,e);e=h*this.direction.dot(c.crossVectors(a,c));if(0>e)return null; -g=h*this.direction.dot(b.cross(a));if(0>g||e+g>f)return null;e=-h*a.dot(d);return 0>e?null:this.at(e/f,k)}}(),applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});Object.assign(ra,{getNormal:function(){var a=new n;return function(b,c,d,e){void 0===e&&(console.warn("THREE.Triangle: .getNormal() target is now required"),e=new n);e.subVectors(d,c);a.subVectors(b, -c);e.cross(a);b=e.lengthSq();return 0=a.x+a.y}}(),getUV:function(){var a=new n;return function(b,c,d,e,f,g,h,k){this.getBarycoord(b,c,d,e,a);k.set(0,0);k.addScaledVector(f,a.x);k.addScaledVector(g,a.y);k.addScaledVector(h,a.z);return k}}(),isFrontFacing:function(){var a=new n,b=new n;return function(c,d,e,f){a.subVectors(e,d);b.subVectors(c,d);return 0>a.cross(b).dot(f)?!0:!1}}()});Object.assign(ra.prototype,{set:function(a,b,c){this.a.copy(a);this.b.copy(b); -this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},getArea:function(){var a=new n,b=new n;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*a.cross(b).length()}}(),getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"), -a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return ra.getNormal(this.a,this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new n);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return ra.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return ra.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return ra.containsPoint(a, -this.a,this.b,this.c)},isFrontFacing:function(a){return ra.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(){var a=new n,b=new n,c=new n,d=new n,e=new n,f=new n;return function(g,h){void 0===h&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),h=new n);var k=this.a,m=this.b,l=this.c;a.subVectors(m,k);b.subVectors(l,k);d.subVectors(g,k);var p=a.dot(d),u=b.dot(d);if(0>=p&&0>=u)return h.copy(k); -e.subVectors(g,m);var t=a.dot(e),q=b.dot(e);if(0<=t&&q<=t)return h.copy(m);var v=p*q-t*u;if(0>=v&&0<=p&&0>=t)return m=p/(p-t),h.copy(k).addScaledVector(a,m);f.subVectors(g,l);g=a.dot(f);var x=b.dot(f);if(0<=x&&g<=x)return h.copy(l);p=g*u-p*x;if(0>=p&&0<=u&&0>=x)return v=u/(u-x),h.copy(k).addScaledVector(b,v);u=t*x-g*q;if(0>=u&&0<=q-t&&0<=g-x)return c.subVectors(l,m),v=(q-t)/(q-t+(g-x)),h.copy(m).addScaledVector(c,v);l=1/(u+p+v);m=p*l;v*=l;return h.copy(k).addScaledVector(a,m).addScaledVector(b,v)}}(), -equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}});var Dh={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017, -darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671, -gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753, -lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739, -orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944, -slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Object.assign(C.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a= -Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){a=O.euclideanModulo(a,1);b=O.clamp(b,0,1);c=O.clamp(c,0,1);0===b?this.r=this.g=this.b=c:(b=.5>=c?c*(1+b):c+b-c*b,c=2*c-b,this.r=pe(c,b,a+1/3),this.g=pe(c,b,a),this.b=pe(c,b,a-1/3));return this},setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")} -var c;if(c=/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b= -Math.min(100,parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){d=parseFloat(c[1])/360;var e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this; -if(6===d)return this.r=parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0=h?k/(e+f):k/(2-e-f);switch(e){case b:g=(c-d)/k+(cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;d.stencilWrite=this.stencilWrite;d.stencilFunc=this.stencilFunc;d.stencilRef=this.stencilRef;d.stencilMask=this.stencilMask;d.stencilFail= -this.stencilFail;d.stencilZFail=this.stencilZFail;d.stencilZPass=this.stencilZPass;this.rotation&&0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);this.linewidth&&1!==this.linewidth&&(d.linewidth=this.linewidth);void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&&(d.gapSize=this.gapSize); -void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0c.far?null:{distance:b, -point:w.clone(),object:a}}function b(b,c,d,e,r,n,w,B,E,C,G){f.fromBufferAttribute(r,E);g.fromBufferAttribute(r,C);h.fromBufferAttribute(r,G);r=b.morphTargetInfluences;if(c.morphTargets&&n&&r){p.set(0,0,0);u.set(0,0,0);t.set(0,0,0);for(var H=0,y=n.length;Hg;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c\n\t#include \n}",fragmentShader:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}", -side:1,blending:0});d.uniforms.tEquirect.value=b;b=new sa(new kb(5,5,5),d);c.add(b);d=new Wb(1,10,1);d.renderTarget=this;d.renderTarget.texture.name="CubeCameraTexture";d.update(a,c);b.geometry.dispose();b.material.dispose();return this};Bb.prototype=Object.create(Y.prototype);Bb.prototype.constructor=Bb;Bb.prototype.isDataTexture=!0;Object.assign(Ya.prototype,{isPlane:!0,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant= -d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new n,b=new n;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d,c);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length(); -this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(){var a=new n; -return function(b,c){void 0===c&&(console.warn("THREE.Plane: .intersectLine() target is now required"),c=new n);var d=b.delta(a),e=this.normal.dot(d);if(0===e){if(0===this.distanceToPoint(b.start))return c.copy(b.start)}else if(e=-(b.start.dot(this.normal)+this.constant)/e,!(0>e||1b&&0a&&0c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4], -h=c[5],k=c[6],m=c[7],l=c[8],p=c[9],n=c[10],t=c[11],q=c[12],v=c[13],x=c[14];c=c[15];b[0].setComponents(f-a,m-g,t-l,c-q).normalize();b[1].setComponents(f+a,m+g,t+l,c+q).normalize();b[2].setComponents(f+d,m+h,t+p,c+v).normalize();b[3].setComponents(f-d,m-h,t-p,c-v).normalize();b[4].setComponents(f-e,m-k,t-n,c-x).normalize();b[5].setComponents(f+e,m+k,t+n,c+x).normalize();return this},intersectsObject:function(){var a=new Wa;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere(); -a.copy(c.boundingSphere).applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSprite:function(){var a=new Wa;return function(b){a.center.set(0,0,0);a.radius=.7071067811865476;a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)d;d++){var e=c[d]; -a.x=0e.distanceToPoint(a))return!1}return!0}}(),containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}});var P={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif",alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif", -aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif",aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif", -begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}", +b,c){this.set(1,b,c,0,a,1,c,0,a,b,1,0,0,0,0,1);return this},compose:function(a,b,c){var d=this.elements,e=b._x,f=b._y,g=b._z,h=b._w,l=e+e,m=f+f,k=g+g;b=e*l;var n=e*m;e*=k;var r=f*m;f*=k;g*=k;l*=h;m*=h;h*=k;k=c.x;var q=c.y;c=c.z;d[0]=(1-(r+g))*k;d[1]=(n+h)*k;d[2]=(e-m)*k;d[3]=0;d[4]=(n-h)*q;d[5]=(1-(b+g))*q;d[6]=(f+l)*q;d[7]=0;d[8]=(e+m)*c;d[9]=(f-l)*c;d[10]=(1-(b+r))*c;d[11]=0;d[12]=a.x;d[13]=a.y;d[14]=a.z;d[15]=1;return this},decompose:function(a,b,c){var d=this.elements,e=Ja.set(d[0],d[1],d[2]).length(), +f=Ja.set(d[4],d[5],d[6]).length(),g=Ja.set(d[8],d[9],d[10]).length();0>this.determinant()&&(e=-e);a.x=d[12];a.y=d[13];a.z=d[14];ja.copy(this);a=1/e;d=1/f;var h=1/g;ja.elements[0]*=a;ja.elements[1]*=a;ja.elements[2]*=a;ja.elements[4]*=d;ja.elements[5]*=d;ja.elements[6]*=d;ja.elements[8]*=h;ja.elements[9]*=h;ja.elements[10]*=h;b.setFromRotationMatrix(ja);c.x=e;c.y=f;c.z=g;return this},makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); +var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),l=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*l;g[9]=0;g[13]=-((c+d)*l);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements; +a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}});var gi=new P,hi=new na;Qb.RotationOrders= +"XYZ YZX ZXY XZY YXZ ZYX".split(" ");Qb.DefaultOrder="XYZ";Object.defineProperties(Qb.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;this._onChangeCallback()}}});Object.assign(Qb.prototype,{isEuler:!0,set:function(a, +b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this._onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=O.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],l=e[5],m=e[9],k=e[2],n=e[6];e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.9999999>Math.abs(g)? +(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(n,l),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.9999999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,l)):(this._y=Math.atan2(-k,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(n,-1,1)),.9999999>Math.abs(n)?(this._y=Math.atan2(-k,e),this._z=Math.atan2(-f,l)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(k,-1,1)),.9999999>Math.abs(k)?(this._x=Math.atan2(n,e),this._z=Math.atan2(h,a)): +(this._x=0,this._z=Math.atan2(-f,l))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.9999999>Math.abs(h)?(this._x=Math.atan2(-m,l),this._y=Math.atan2(-k,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.9999999>Math.abs(f)?(this._x=Math.atan2(n,l),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;!1!==c&&this._onChangeCallback();return this},setFromQuaternion:function(a, +b,c){gi.makeRotationFromQuaternion(a);return this.setFromRotationMatrix(gi,b,c)},setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(a){hi.setFromEuler(this);return this.setFromQuaternion(hi,a)},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a= +[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new n(this._x,this._y,this._z)},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});Object.assign(Qf.prototype,{set:function(a){this.mask=1<e&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d); +this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,l=a.count;he&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y), +(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(a){this.clampPoint(a.center,jb);return jb.distanceToSquared(a.center)<=a.radius*a.radius},intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(a){if(this.isEmpty())return!1;this.getCenter(xe);tf.subVectors(this.max,xe);od.subVectors(a.a,xe);pd.subVectors(a.b,xe);qd.subVectors(a.c,xe);Mb.subVectors(pd,od);Nb.subVectors(qd,pd);qc.subVectors(od,qd);a=[0,-Mb.z,Mb.y,0,-Nb.z,Nb.y,0,-qc.z, +qc.y,Mb.z,0,-Mb.x,Nb.z,0,-Nb.x,qc.z,0,-qc.x,-Mb.y,Mb.x,0,-Nb.y,Nb.x,0,-qc.y,qc.x,0];if(!Rf(a,od,pd,qd,tf))return!1;a=[1,0,0,0,1,0,0,0,1];if(!Rf(a,od,pd,qd,tf))return!1;uf.crossVectors(Mb,Nb);a=[uf.x,uf.y,uf.z];return Rf(a,od,pd,qd,tf)},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"),b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return jb.copy(a).clamp(this.min,this.max).sub(a).length()},getBoundingSphere:function(a){void 0=== +a&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(a.center);a.radius=.5*this.getSize(jb).length();return a},intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(a){if(this.isEmpty())return this;wb[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(a);wb[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(a); +wb[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(a);wb[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(a);wb[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(a);wb[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(a);wb[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(a);wb[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(a);this.setFromPoints(wb);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&& +a.max.equals(this.max)}});var nk=new ab;Object.assign(nb.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(a,b){var c=this.center;void 0!==b?c.copy(b):nk.setFromPoints(a).getCenter(c);for(var d=b=0,e=a.length;d= +this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a); +void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"),a=new ab);a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this}, +translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}});var xb=new n,Jg=new n,vf=new n,Ob=new n,Kg=new n,wf=new n,Lg=new n;Object.assign(Sb.prototype,{set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){void 0===b&&(console.warn("THREE.Ray: .at() target is now required"), +b=new n);return b.copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(a){this.origin.copy(this.at(a,xb));return this},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Ray: .closestPointToPoint() target is now required"),b=new n);b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))}, +distanceSqToPoint:function(a){var b=xb.subVectors(a,this.origin).dot(this.direction);if(0>b)return this.origin.distanceToSquared(a);xb.copy(this.direction).multiplyScalar(b).add(this.origin);return xb.distanceToSquared(a)},distanceSqToSegment:function(a,b,c,d){Jg.copy(a).add(b).multiplyScalar(.5);vf.copy(b).sub(a).normalize();Ob.copy(this.origin).sub(Jg);var e=.5*a.distanceTo(b),f=-this.direction.dot(vf),g=Ob.dot(this.direction),h=-Ob.dot(vf),l=Ob.lengthSq(),m=Math.abs(1-f*f);if(0=-k?b<=k?(e=1/m,a*=e,b*=e,f=a*(a+f*b+2*g)+b*(f*a+b+2*h)+l):(b=e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):(b=-e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):b<=-k?(a=Math.max(0,-(-f*e+g)),b=0a)return null;a=Math.sqrt(a-d);d=c-a;c+=a;return 0>d&&0>c?null:0>d?this.at(c,b):this.at(d,b)},intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+ +a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){a=this.distanceToPlane(a);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y- +f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null;if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(a){return null!==this.intersectBox(a,xb)},intersectTriangle:function(a,b,c,d,e){Kg.subVectors(b,a);wf.subVectors(c,a);Lg.crossVectors(Kg,wf);b=this.direction.dot(Lg);if(0b)d=-1,b=-b;else return null; +Ob.subVectors(this.origin,a);a=d*this.direction.dot(wf.crossVectors(Ob,wf));if(0>a)return null;c=d*this.direction.dot(Kg.cross(Ob));if(0>c||a+c>b)return null;a=-d*Ob.dot(Lg);return 0>a?null:this.at(a/b,e)},applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});var Ya=new n,yb=new n,Mg=new n,zb=new n,rd=new n,sd=new n,mi=new n,Ng=new n,Og=new n,Pg=new n;Object.assign(ia, +{getNormal:function(a,b,c,d){void 0===d&&(console.warn("THREE.Triangle: .getNormal() target is now required"),d=new n);d.subVectors(c,b);Ya.subVectors(a,b);d.cross(Ya);a=d.lengthSq();return 0=zb.x+zb.y},getUV:function(a,b,c,d,e,f,g,h){this.getBarycoord(a,b,c,d,zb);h.set(0,0);h.addScaledVector(e,zb.x);h.addScaledVector(f,zb.y);h.addScaledVector(g,zb.z);return h},isFrontFacing:function(a,b,c,d){Ya.subVectors(c,b);yb.subVectors(a,b);return 0>Ya.cross(yb).dot(d)?!0:!1}});Object.assign(ia.prototype,{set:function(a, +b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},getArea:function(){Ya.subVectors(this.c,this.b);yb.subVectors(this.a,this.b);return.5*Ya.cross(yb).length()},getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"), +a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return ia.getNormal(this.a,this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new n);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return ia.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return ia.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return ia.containsPoint(a, +this.a,this.b,this.c)},isFrontFacing:function(a){return ia.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),b=new n);var c=this.a,d=this.b,e=this.c;rd.subVectors(d,c);sd.subVectors(e,c);Ng.subVectors(a,c);var f=rd.dot(Ng),g=sd.dot(Ng);if(0>=f&&0>=g)return b.copy(c);Og.subVectors(a,d);var h=rd.dot(Og),l=sd.dot(Og);if(0<=h&&l<= +h)return b.copy(d);var m=f*l-h*g;if(0>=m&&0<=f&&0>=h)return d=f/(f-h),b.copy(c).addScaledVector(rd,d);Pg.subVectors(a,e);a=rd.dot(Pg);var k=sd.dot(Pg);if(0<=k&&a<=k)return b.copy(e);f=a*g-f*k;if(0>=f&&0<=g&&0>=k)return m=g/(g-k),b.copy(c).addScaledVector(sd,m);g=h*k-a*l;if(0>=g&&0<=l-h&&0<=a-k)return mi.subVectors(e,d),m=(l-h)/(l-h+(a-k)),b.copy(d).addScaledVector(mi,m);e=1/(g+f+m);d=f*e;m*=e;return b.copy(c).addScaledVector(rd,d).addScaledVector(sd,m)},equals:function(a){return a.a.equals(this.a)&& +a.b.equals(this.b)&&a.c.equals(this.c)}});var ok={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017, +darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504, +green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734, +lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734, +palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407, +steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},Aa={h:0,s:0,l:0},xf={h:0,s:0,l:0};Object.assign(J.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a); +this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){a=O.euclideanModulo(a,1);b=O.clamp(b,0,1);c=O.clamp(c,0,1);0===b?this.r=this.g=this.b=c:(b=.5>=c?c*(1+b):c+b-c*b,c=2*c-b,this.r=Sf(c,b,a+1/3),this.g=Sf(c,b,a),this.b=Sf(c,b,a-1/3));return this},setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c= +/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100, +parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){d=parseFloat(c[1])/360;var e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this;if(6===d)return this.r= +parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0=h?l/(e+f):l/(2-e-f);switch(e){case b:g=(c- +d)/l+(cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;d.stencilWrite=this.stencilWrite;d.stencilFunc= +this.stencilFunc;d.stencilRef=this.stencilRef;d.stencilMask=this.stencilMask;d.stencilFail=this.stencilFail;d.stencilZFail=this.stencilZFail;d.stencilZPass=this.stencilZPass;this.rotation&&0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);this.linewidth&&1!==this.linewidth&&(d.linewidth=this.linewidth); +void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&&(d.gapSize=this.gapSize);void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c\n\t#include \n}", +fragmentShader:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}",side:1,blending:0});d.uniforms.tEquirect.value=b;b=new ra(new Bb(5, +5,5),d);c.add(b);d=new Dc(1,10,1);d.renderTarget=this;d.renderTarget.texture.name="CubeCameraTexture";d.update(a,c);b.geometry.dispose();b.material.dispose();return this};Zb.prototype=Object.create(ba.prototype);Zb.prototype.constructor=Zb;Zb.prototype.isDataTexture=!0;var Ug=new n,qk=new n,rk=new ta;Object.assign(cb.prototype,{isPlane:!0,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a, +b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(a,b,c){b=Ug.subVectors(c,b).cross(qk.subVectors(a,b)).normalize();this.setFromNormalAndCoplanarPoint(b,a);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*= +-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(a,b){void 0===b&&(console.warn("THREE.Plane: .intersectLine() target is now required"),b=new n);var c= +a.delta(Ug),d=this.normal.dot(c);if(0===d){if(0===this.distanceToPoint(a.start))return b.copy(a.start)}else if(d=-(a.start.dot(this.normal)+this.constant)/d,!(0>d||1b&&0a&&0c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],l=c[6],k=c[7],n=c[8],u=c[9],r=c[10],q=c[11],t=c[12],y=c[13],w=c[14];c=c[15];b[0].setComponents(f-a,k-g,q-n,c-t).normalize();b[1].setComponents(f+a,k+g,q+n,c+t).normalize();b[2].setComponents(f+ +d,k+h,q+u,c+y).normalize();b[3].setComponents(f-d,k-h,q-u,c-y).normalize();b[4].setComponents(f-e,k-l,q-r,c-w).normalize();b[5].setComponents(f+e,k+l,q+r,c+w).normalize();return this},intersectsObject:function(a){var b=a.geometry;null===b.boundingSphere&&b.computeBoundingSphere();td.copy(b.boundingSphere).applyMatrix4(a.matrixWorld);return this.intersectsSphere(td)},intersectsSprite:function(a){td.center.set(0,0,0);td.radius=.7071067811865476;td.applyMatrix4(a.matrixWorld);return this.intersectsSphere(td)}, +intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)c;c++){var d=b[c];Af.x=0d.distanceToPoint(Af))return!1}return!0},containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}});var K={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif", +alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif", +aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif", bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif", clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif", -clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif", -color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}", +clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif", +color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}", cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif", defaultnormal_vertex:"vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif", emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",encodings_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}", -envmap_fragment:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif", -envmap_pars_fragment:"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif", -envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif", -envmap_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif", -fog_vertex:"#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif", +envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif", +envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif", +envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif", +envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif",fog_vertex:"#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif", +fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif", gradientmap_pars_fragment:"#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif", lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif", lights_pars_begin:"uniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif", lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)", -lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif", -lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#endif\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\tfloat clearCoatInv = 1.0 - clearCoatDHR;\n\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec3 singleScattering = vec3( 0.0 );\n\t\tvec3 multiScattering = vec3( 0.0 );\n\t\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\t\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\t\treflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;\n\t\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\t\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n\t#else\n\t\treflectedLight.indirectSpecular += clearCoatInv * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#endif\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}", -lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif", -lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif", -lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, irradiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif", +lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = saturate( clearcoat );\tmaterial.clearcoatRoughness = clamp( clearcoatRoughness, 0.04, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif", +lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}", +lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif", +lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif", +lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif", logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif",map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif", map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif",map_particle_pars_fragment:"#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif", metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif", morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif", -normal_fragment_begin:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif", -normal_fragment_maps:"#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\t#ifdef USE_TANGENT\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy = normalScale * mapN.xy;\n\t\t\tnormal = normalize( vTBN * mapN );\n\t\t#else\n\t\t\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\t\t#endif\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif", -normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#else\n\t\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\t\tvec2 st0 = dFdx( vUv.st );\n\t\t\tvec2 st1 = dFdy( vUv.st );\n\t\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\t\tvec3 N = normalize( surf_norm );\n\t\t\tmat3 tsn = mat3( S, T, N );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy *= normalScale;\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\treturn normalize( tsn * mapN );\n\t\t}\n\t#endif\n#endif", -packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}", -premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#if defined( DITHERING )\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif", -roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif", -shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif", -shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif", -shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}", +normal_fragment_begin:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;", +normal_fragment_maps:"#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, normalScale, normalMap );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif", +normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec2 normalScale, in sampler2D normalMap ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvec3 NfromST = cross( S, T );\n\t\t\tif( dot( NfromST, N ) > 0.0 ) {\n\t\t\t\tS *= -1.0;\n\t\t\t\tT *= -1.0;\n\t\t\t}\n\t\t#else\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif", +clearcoat_normal_fragment_begin:"#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, clearcoatNormal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = clearcoatNormalScale * mapN.xy;\n\t\tclearcoatNormal = normalize( vTBN * mapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatNormalScale, clearcoatNormalMap );\n\t#endif\n#endif", +clearcoat_normalmap_pars_fragment:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 encodeHalfRGBA ( vec2 v ) {\n\tvec4 encoded = vec4( 0.0 );\n\tconst vec2 offset = vec2( 1.0 / 255.0, 0.0 );\n\tencoded.xy = vec2( v.x, fract( v.x * 255.0 ) );\n\tencoded.xy = encoded.xy - ( encoded.yy * offset );\n\tencoded.zw = vec2( v.y, fract( v.y * 255.0 ) );\n\tencoded.zw = encoded.zw - ( encoded.ww * offset );\n\treturn encoded;\n}\nvec2 decodeHalfRGBA( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}", +premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif", +roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn decodeHalfRGBA( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif", +shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif", +shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif", +shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}", skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif", skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif", specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}", -uv_pars_fragment:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif", -uv_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif", -uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif",background_frag:"uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}",background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}", +uv_pars_fragment:"#ifdef USE_UV\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#ifdef USE_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif",uv_vertex:"#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif",uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif", +worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif",background_frag:"uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}",background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}", cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}",cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}", depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}", depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", @@ -616,379 +623,374 @@ distanceRGBA_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}", equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}", -meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", -meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshlambert_vert:"#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}", -meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}", -meshphysical_frag:"#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", -meshphysical_vert:"#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}", -normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}", -normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", +meshphysical_frag:"#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSPARENCY\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSPARENCY\n\tuniform float transparency;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}", +normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}", +normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}", shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}",shadow_vert:"#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}", sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"}, -I={common:{diffuse:{value:new C(15658734)},opacity:{value:1},map:{value:null},uvTransform:{value:new ja},alphaMap:{value:null}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98},maxMipLevel:{value:0}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null}, -normalScale:{value:new D(1,1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:2.5E-4},fogNear:{value:1},fogFar:{value:2E3},fogColor:{value:new C(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{},shadow:{},shadowBias:{}, +H={common:{diffuse:{value:new J(15658734)},opacity:{value:1},map:{value:null},uvTransform:{value:new ta},alphaMap:{value:null}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98},maxMipLevel:{value:0}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null}, +normalScale:{value:new v(1,1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:2.5E-4},fogNear:{value:1},fogFar:{value:2E3},fogColor:{value:new J(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{},shadow:{},shadowBias:{}, shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},spotShadowMap:{value:[]},spotShadowMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}}, -pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}}},points:{diffuse:{value:new C(15658734)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},uvTransform:{value:new ja}},sprite:{diffuse:{value:new C(15658734)},opacity:{value:1},center:{value:new D(.5,.5)},rotation:{value:0},map:{value:null},uvTransform:{value:new ja}}}, -Za={basic:{uniforms:oa([I.common,I.specularmap,I.envmap,I.aomap,I.lightmap,I.fog]),vertexShader:P.meshbasic_vert,fragmentShader:P.meshbasic_frag},lambert:{uniforms:oa([I.common,I.specularmap,I.envmap,I.aomap,I.lightmap,I.emissivemap,I.fog,I.lights,{emissive:{value:new C(0)}}]),vertexShader:P.meshlambert_vert,fragmentShader:P.meshlambert_frag},phong:{uniforms:oa([I.common,I.specularmap,I.envmap,I.aomap,I.lightmap,I.emissivemap,I.bumpmap,I.normalmap,I.displacementmap,I.gradientmap,I.fog,I.lights,{emissive:{value:new C(0)}, -specular:{value:new C(1118481)},shininess:{value:30}}]),vertexShader:P.meshphong_vert,fragmentShader:P.meshphong_frag},standard:{uniforms:oa([I.common,I.envmap,I.aomap,I.lightmap,I.emissivemap,I.bumpmap,I.normalmap,I.displacementmap,I.roughnessmap,I.metalnessmap,I.fog,I.lights,{emissive:{value:new C(0)},roughness:{value:.5},metalness:{value:.5},envMapIntensity:{value:1}}]),vertexShader:P.meshphysical_vert,fragmentShader:P.meshphysical_frag},matcap:{uniforms:oa([I.common,I.bumpmap,I.normalmap,I.displacementmap, -I.fog,{matcap:{value:null}}]),vertexShader:P.meshmatcap_vert,fragmentShader:P.meshmatcap_frag},points:{uniforms:oa([I.points,I.fog]),vertexShader:P.points_vert,fragmentShader:P.points_frag},dashed:{uniforms:oa([I.common,I.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:P.linedashed_vert,fragmentShader:P.linedashed_frag},depth:{uniforms:oa([I.common,I.displacementmap]),vertexShader:P.depth_vert,fragmentShader:P.depth_frag},normal:{uniforms:oa([I.common,I.bumpmap,I.normalmap, -I.displacementmap,{opacity:{value:1}}]),vertexShader:P.normal_vert,fragmentShader:P.normal_frag},sprite:{uniforms:oa([I.sprite,I.fog]),vertexShader:P.sprite_vert,fragmentShader:P.sprite_frag},background:{uniforms:{uvTransform:{value:new ja},t2D:{value:null}},vertexShader:P.background_vert,fragmentShader:P.background_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:P.cube_vert,fragmentShader:P.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:P.equirect_vert, -fragmentShader:P.equirect_frag},distanceRGBA:{uniforms:oa([I.common,I.displacementmap,{referencePosition:{value:new n},nearDistance:{value:1},farDistance:{value:1E3}}]),vertexShader:P.distanceRGBA_vert,fragmentShader:P.distanceRGBA_frag},shadow:{uniforms:oa([I.lights,I.fog,{color:{value:new C(0)},opacity:{value:1}}]),vertexShader:P.shadow_vert,fragmentShader:P.shadow_frag}};Za.physical={uniforms:oa([Za.standard.uniforms,{clearCoat:{value:0},clearCoatRoughness:{value:0}}]),vertexShader:P.meshphysical_vert, -fragmentShader:P.meshphysical_frag};Mc.prototype=Object.create(N.prototype);Mc.prototype.constructor=Mc;Cb.prototype=Object.create(B.prototype);Cb.prototype.constructor=Cb;db.prototype=Object.create(Y.prototype);db.prototype.constructor=db;db.prototype.isCubeTexture=!0;Object.defineProperty(db.prototype,"images",{get:function(){return this.image},set:function(a){this.image=a}});Xb.prototype=Object.create(Y.prototype);Xb.prototype.constructor=Xb;Xb.prototype.isDataTexture2DArray=!0;Yb.prototype=Object.create(Y.prototype); -Yb.prototype.constructor=Yb;Yb.prototype.isDataTexture3D=!0;var qf=new Y,Ig=new Xb,Kg=new Yb,rf=new db,kf=[],mf=[],pf=new Float32Array(16),of=new Float32Array(9),nf=new Float32Array(4);sf.prototype.updateCache=function(a){var b=this.cache;a instanceof Float32Array&&b.length!==a.length&&(this.cache=new Float32Array(a.length));pa(b,a)};tf.prototype.setValue=function(a,b,c){for(var d=this.seq,e=0,f=d.length;e!==f;++e){var g=d[e];g.setValue(a,b[g.id],c)}};var te=/([\w\d_]+)(\])?(\[|\.)?/g;nb.prototype.setValue= -function(a,b,c,d){b=this.map[b];void 0!==b&&b.setValue(a,c,d)};nb.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};nb.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=b[e],h=c[g.id];!1!==h.needsUpdate&&g.setValue(a,h.value,d)}};nb.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f=a[d];f.id in b&&c.push(f)}return c};var kh=0,sh=0;ob.prototype=Object.create(S.prototype);ob.prototype.constructor=ob;ob.prototype.isMeshDepthMaterial=!0; -ob.prototype.copy=function(a){S.prototype.copy.call(this,a);this.depthPacking=a.depthPacking;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;return this};pb.prototype=Object.create(S.prototype);pb.prototype.constructor=pb;pb.prototype.isMeshDistanceMaterial= -!0;pb.prototype.copy=function(a){S.prototype.copy.call(this,a);this.referencePosition.copy(a.referencePosition);this.nearDistance=a.nearDistance;this.farDistance=a.farDistance;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;return this};$b.prototype=Object.assign(Object.create(G.prototype),{constructor:$b,isGroup:!0});Qc.prototype= -Object.assign(Object.create(ka.prototype),{constructor:Qc,isArrayCamera:!0});var Gf=new n,Hf=new n;Object.assign(ve.prototype,na.prototype);Object.assign(If.prototype,na.prototype);Object.assign(Id.prototype,{isFogExp2:!0,clone:function(){return new Id(this.color,this.density)},toJSON:function(){return{type:"FogExp2",color:this.color.getHex(),density:this.density}}});Object.assign(Jd.prototype,{isFog:!0,clone:function(){return new Jd(this.color,this.near,this.far)},toJSON:function(){return{type:"Fog", -color:this.color.getHex(),near:this.near,far:this.far}}});Object.defineProperty(Db.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(Db.prototype,{isInterleavedBuffer:!0,onUploadCallback:function(){},setArray:function(a){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.count=void 0!==a?a.length/this.stride:0;this.array=a;return this},setDynamic:function(a){this.dynamic=a;return this},copy:function(a){this.array=new a.array.constructor(a.array); -this.count=a.count;this.stride=a.stride;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.stride;c*=b.stride;for(var d=0,e=this.stride;de.far||f.push({distance:q,point:b.clone(),uv:ra.getUV(b,h,k,m,l,p,u,new D),face:null, -object:this})}}(),clone:function(){return(new this.constructor(this.material)).copy(this)},copy:function(a){G.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});Tc.prototype=Object.assign(Object.create(G.prototype),{constructor:Tc,isLOD:!0,copy:function(a){G.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;ef||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}else for(g=0,q=t.length/3-1;gf||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v,point:h.clone().applyMatrix4(this.matrixWorld), -index:g,face:null,faceIndex:null,object:this}))}else if(g.isGeometry)for(k=g.vertices,m=k.length,g=0;gf||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});U.prototype=Object.assign(Object.create(X.prototype), -{constructor:U,isLineSegments:!0,computeLineDistances:function(){var a=new n,b=new n;return function(){var c=this.geometry;if(c.isBufferGeometry)if(null===c.index){for(var d=c.attributes.position,e=[],f=0,g=d.count;fd.far||e.push({distance:a,distanceToRay:Math.sqrt(f),point:p.clone(),index:c,face:null,object:g}))}var g=this,h=this.geometry,k=this.matrixWorld,m=d.params.Points.threshold;null===h.boundingSphere&& -h.computeBoundingSphere();c.copy(h.boundingSphere);c.applyMatrix4(k);c.radius+=m;if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);m/=(this.scale.x+this.scale.y+this.scale.z)/3;var l=m*m;m=new n;var p=new n;if(h.isBufferGeometry){var u=h.index;h=h.attributes.position.array;if(null!==u){var t=u.array;u=0;for(var q=t.length;u=a.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}});cc.prototype=Object.create(Y.prototype);cc.prototype.constructor=cc;cc.prototype.isCompressedTexture=!0;Vc.prototype=Object.create(Y.prototype);Vc.prototype.constructor=Vc;Vc.prototype.isCanvasTexture=!0;Wc.prototype=Object.create(Y.prototype); -Wc.prototype.constructor=Wc;Wc.prototype.isDepthTexture=!0;dc.prototype=Object.create(B.prototype);dc.prototype.constructor=dc;Xc.prototype=Object.create(N.prototype);Xc.prototype.constructor=Xc;ec.prototype=Object.create(B.prototype);ec.prototype.constructor=ec;Yc.prototype=Object.create(N.prototype);Yc.prototype.constructor=Yc;Aa.prototype=Object.create(B.prototype);Aa.prototype.constructor=Aa;Zc.prototype=Object.create(N.prototype);Zc.prototype.constructor=Zc;fc.prototype=Object.create(Aa.prototype); -fc.prototype.constructor=fc;$c.prototype=Object.create(N.prototype);$c.prototype.constructor=$c;Eb.prototype=Object.create(Aa.prototype);Eb.prototype.constructor=Eb;ad.prototype=Object.create(N.prototype);ad.prototype.constructor=ad;gc.prototype=Object.create(Aa.prototype);gc.prototype.constructor=gc;bd.prototype=Object.create(N.prototype);bd.prototype.constructor=bd;hc.prototype=Object.create(Aa.prototype);hc.prototype.constructor=hc;cd.prototype=Object.create(N.prototype);cd.prototype.constructor= -cd;Fb.prototype=Object.create(B.prototype);Fb.prototype.constructor=Fb;Fb.prototype.toJSON=function(){var a=B.prototype.toJSON.call(this);a.path=this.parameters.path.toJSON();return a};dd.prototype=Object.create(N.prototype);dd.prototype.constructor=dd;ic.prototype=Object.create(B.prototype);ic.prototype.constructor=ic;ed.prototype=Object.create(N.prototype);ed.prototype.constructor=ed;jc.prototype=Object.create(B.prototype);jc.prototype.constructor=jc;var Fh={triangulate:function(a,b,c){c=c||2;var d= -b&&b.length,e=d?b[0]*c:a.length,f=Kf(a,0,e,c,!0),g=[];if(!f||f.next===f.prev)return g;var h;if(d){var k=c;d=[];var m;var l=0;for(m=b.length;l80*c){var t=h=a[0];var q=d=a[1];for(k=c;kh&&(h=l),b>d&&(d=b);h=Math.max(h-t,d-q);h=0!==h?1/h: -0}hd(f,g,c,t,q,h);return g}},eb={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;eeb.area(a)},triangulateShape:function(a,b){var c=[],d=[],e=[];Of(a);Pf(c,a);var f=a.length;b.forEach(Of);for(a=0;aMath.abs(g-k)?[new D(a,1-c),new D(h,1-d),new D(m,1-e),new D(n,1-b)]:[new D(g,1-c),new D(k,1-d),new D(l,1-e),new D(u,1-b)]}};jd.prototype=Object.create(N.prototype);jd.prototype.constructor=jd;lc.prototype=Object.create($a.prototype);lc.prototype.constructor=lc;kd.prototype=Object.create(N.prototype);kd.prototype.constructor=kd;sb.prototype=Object.create(B.prototype);sb.prototype.constructor= -sb;ld.prototype=Object.create(N.prototype);ld.prototype.constructor=ld;mc.prototype=Object.create(B.prototype);mc.prototype.constructor=mc;md.prototype=Object.create(N.prototype);md.prototype.constructor=md;nc.prototype=Object.create(B.prototype);nc.prototype.constructor=nc;Ib.prototype=Object.create(N.prototype);Ib.prototype.constructor=Ib;Ib.prototype.toJSON=function(){var a=N.prototype.toJSON.call(this);return Rf(this.parameters.shapes,a)};Jb.prototype=Object.create(B.prototype);Jb.prototype.constructor= -Jb;Jb.prototype.toJSON=function(){var a=B.prototype.toJSON.call(this);return Rf(this.parameters.shapes,a)};oc.prototype=Object.create(B.prototype);oc.prototype.constructor=oc;Kb.prototype=Object.create(N.prototype);Kb.prototype.constructor=Kb;fb.prototype=Object.create(B.prototype);fb.prototype.constructor=fb;nd.prototype=Object.create(Kb.prototype);nd.prototype.constructor=nd;od.prototype=Object.create(fb.prototype);od.prototype.constructor=od;pd.prototype=Object.create(N.prototype);pd.prototype.constructor= -pd;pc.prototype=Object.create(B.prototype);pc.prototype.constructor=pc;var ua=Object.freeze({WireframeGeometry:dc,ParametricGeometry:Xc,ParametricBufferGeometry:ec,TetrahedronGeometry:Zc,TetrahedronBufferGeometry:fc,OctahedronGeometry:$c,OctahedronBufferGeometry:Eb,IcosahedronGeometry:ad,IcosahedronBufferGeometry:gc,DodecahedronGeometry:bd,DodecahedronBufferGeometry:hc,PolyhedronGeometry:Yc,PolyhedronBufferGeometry:Aa,TubeGeometry:cd,TubeBufferGeometry:Fb,TorusKnotGeometry:dd,TorusKnotBufferGeometry:ic, -TorusGeometry:ed,TorusBufferGeometry:jc,TextGeometry:jd,TextBufferGeometry:lc,SphereGeometry:kd,SphereBufferGeometry:sb,RingGeometry:ld,RingBufferGeometry:mc,PlaneGeometry:Mc,PlaneBufferGeometry:Cb,LatheGeometry:md,LatheBufferGeometry:nc,ShapeGeometry:Ib,ShapeBufferGeometry:Jb,ExtrudeGeometry:Hb,ExtrudeBufferGeometry:$a,EdgesGeometry:oc,ConeGeometry:nd,ConeBufferGeometry:od,CylinderGeometry:Kb,CylinderBufferGeometry:fb,CircleGeometry:pd,CircleBufferGeometry:pc,BoxGeometry:Vb,BoxBufferGeometry:kb}); -Lb.prototype=Object.create(S.prototype);Lb.prototype.constructor=Lb;Lb.prototype.isShadowMaterial=!0;Lb.prototype.copy=function(a){S.prototype.copy.call(this,a);this.color.copy(a.color);return this};qc.prototype=Object.create(va.prototype);qc.prototype.constructor=qc;qc.prototype.isRawShaderMaterial=!0;ab.prototype=Object.create(S.prototype);ab.prototype.constructor=ab;ab.prototype.isMeshStandardMaterial=!0;ab.prototype.copy=function(a){S.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color); -this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale= -a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this}; -Mb.prototype=Object.create(ab.prototype);Mb.prototype.constructor=Mb;Mb.prototype.isMeshPhysicalMaterial=!0;Mb.prototype.copy=function(a){ab.prototype.copy.call(this,a);this.defines={PHYSICAL:""};this.reflectivity=a.reflectivity;this.clearCoat=a.clearCoat;this.clearCoatRoughness=a.clearCoatRoughness;return this};Ma.prototype=Object.create(S.prototype);Ma.prototype.constructor=Ma;Ma.prototype.isMeshPhongMaterial=!0;Ma.prototype.copy=function(a){S.prototype.copy.call(this,a);this.color.copy(a.color); -this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale= -a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Nb.prototype= -Object.create(Ma.prototype);Nb.prototype.constructor=Nb;Nb.prototype.isMeshToonMaterial=!0;Nb.prototype.copy=function(a){Ma.prototype.copy.call(this,a);this.gradientMap=a.gradientMap;return this};Ob.prototype=Object.create(S.prototype);Ob.prototype.constructor=Ob;Ob.prototype.isMeshNormalMaterial=!0;Ob.prototype.copy=function(a){S.prototype.copy.call(this,a);this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale); -this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Pb.prototype=Object.create(S.prototype);Pb.prototype.constructor=Pb;Pb.prototype.isMeshLambertMaterial=!0;Pb.prototype.copy=function(a){S.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map; -this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap; -this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Qb.prototype=Object.create(S.prototype);Qb.prototype.constructor=Qb;Qb.prototype.isMeshMatcapMaterial=!0;Qb.prototype.copy=function(a){S.prototype.copy.call(this,a);this.defines={MATCAP:""};this.color.copy(a.color);this.matcap=a.matcap;this.map=a.map;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType; -this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.alphaMap=a.alphaMap;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Rb.prototype=Object.create(W.prototype);Rb.prototype.constructor=Rb;Rb.prototype.isLineDashedMaterial=!0;Rb.prototype.copy=function(a){W.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize= -a.gapSize;return this};var Gh=Object.freeze({ShadowMaterial:Lb,SpriteMaterial:rb,RawShaderMaterial:qc,ShaderMaterial:va,PointsMaterial:La,MeshPhysicalMaterial:Mb,MeshStandardMaterial:ab,MeshPhongMaterial:Ma,MeshToonMaterial:Nb,MeshNormalMaterial:Ob,MeshLambertMaterial:Pb,MeshDepthMaterial:ob,MeshDistanceMaterial:pb,MeshBasicMaterial:la,MeshMatcapMaterial:Qb,LineDashedMaterial:Rb,LineBasicMaterial:W,Material:S}),aa={arraySlice:function(a,b,c){return aa.isTypedArray(a)?new a.constructor(a.subarray(b, -void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&&a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,b,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,k=0;k!== -b;++k)e[g++]=a[h+k];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!==f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];while(void 0!==f)}}}};Object.assign(Ea.prototype,{evaluate:function(a){var b= -this.parameterPositions,c=this._cachedIndex,d=b[c],e=b[c-1];a:{b:{c:{d:if(!(a=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,aa.far||b.push({distance:e,point:ye.clone(),uv:ia.getUV(ye,Bf,ze,Cf,oi,Vg,pi,new v),face:null,object:this})},clone:function(){return(new this.constructor(this.material)).copy(this)},copy:function(a){B.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});var Df=new n,qi=new n;Md.prototype=Object.assign(Object.create(B.prototype),{constructor:Md,isLOD:!0,copy:function(a){B.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=b[c].distance)b[c-1].object.visible=!1,b[c].object.visible=!0;else break;for(;cc||(h.applyMatrix4(this.matrixWorld),r=a.ray.origin.distanceTo(h),ra.far||b.push({distance:r,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null,object:this}))}}else for(d=0,u=p.length/3-1;dc||(h.applyMatrix4(this.matrixWorld),r=a.ray.origin.distanceTo(h),ra.far||b.push({distance:r,point:e.clone().applyMatrix4(this.matrixWorld), +index:d,face:null,faceIndex:null,object:this}))}else if(d.isGeometry)for(f=d.vertices,g=f.length,d=0;dc||(h.applyMatrix4(this.matrixWorld),r=a.ray.origin.distanceTo(h),ra.far||b.push({distance:r,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null,object:this}))}},clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});var Ff=new n,Gf=new n;R.prototype=Object.assign(Object.create(ca.prototype), +{constructor:R,isLineSegments:!0,computeLineDistances:function(){var a=this.geometry;if(a.isBufferGeometry)if(null===a.index){for(var b=a.attributes.position,c=[],d=0,e=b.count;d=a.HAVE_CURRENT_DATA&& +(this.needsUpdate=!0)}});Lc.prototype=Object.create(ba.prototype);Lc.prototype.constructor=Lc;Lc.prototype.isCompressedTexture=!0;Od.prototype=Object.create(ba.prototype);Od.prototype.constructor=Od;Od.prototype.isCanvasTexture=!0;Pd.prototype=Object.create(ba.prototype);Pd.prototype.constructor=Pd;Pd.prototype.isDepthTexture=!0;Mc.prototype=Object.create(D.prototype);Mc.prototype.constructor=Mc;Qd.prototype=Object.create(G.prototype);Qd.prototype.constructor=Qd;Nc.prototype=Object.create(D.prototype); +Nc.prototype.constructor=Nc;Rd.prototype=Object.create(G.prototype);Rd.prototype.constructor=Rd;pa.prototype=Object.create(D.prototype);pa.prototype.constructor=pa;Sd.prototype=Object.create(G.prototype);Sd.prototype.constructor=Sd;Oc.prototype=Object.create(pa.prototype);Oc.prototype.constructor=Oc;Td.prototype=Object.create(G.prototype);Td.prototype.constructor=Td;bc.prototype=Object.create(pa.prototype);bc.prototype.constructor=bc;Ud.prototype=Object.create(G.prototype);Ud.prototype.constructor= +Ud;Pc.prototype=Object.create(pa.prototype);Pc.prototype.constructor=Pc;Vd.prototype=Object.create(G.prototype);Vd.prototype.constructor=Vd;Qc.prototype=Object.create(pa.prototype);Qc.prototype.constructor=Qc;Wd.prototype=Object.create(G.prototype);Wd.prototype.constructor=Wd;cc.prototype=Object.create(D.prototype);cc.prototype.constructor=cc;cc.prototype.toJSON=function(){var a=D.prototype.toJSON.call(this);a.path=this.parameters.path.toJSON();return a};Xd.prototype=Object.create(G.prototype);Xd.prototype.constructor= +Xd;Rc.prototype=Object.create(D.prototype);Rc.prototype.constructor=Rc;Yd.prototype=Object.create(G.prototype);Yd.prototype.constructor=Yd;Sc.prototype=Object.create(D.prototype);Sc.prototype.constructor=Sc;var tk={triangulate:function(a,b,c){c=c||2;var d=b&&b.length,e=d?b[0]*c:a.length,f=Lh(a,0,e,c,!0),g=[];if(!f||f.next===f.prev)return g;var h;if(d){var l=c;d=[];var k;var n=0;for(k=b.length;n80*c){var q=h=a[0];var t=d=a[1];for(l=c;lh&&(h=n),b>d&&(d=b);h=Math.max(h-q,d-t);h=0!==h?1/h:0}ae(f,g,c,q,t,h);return g}},qb={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;eqb.area(a)},triangulateShape:function(a,b){var c=[],d=[],e=[];Ph(a);Qh(c,a);var f=a.length;b.forEach(Ph); +for(a=0;aMath.abs(g-l)?[new v(a,1-c),new v(h,1-d),new v(k,1-e),new v(u,1-b)]:[new v(g,1-c),new v(l,1-d),new v(n,1-e),new v(r,1-b)]}};ce.prototype=Object.create(G.prototype); +ce.prototype.constructor=ce;Uc.prototype=Object.create(eb.prototype);Uc.prototype.constructor=Uc;de.prototype=Object.create(G.prototype);de.prototype.constructor=de;Ib.prototype=Object.create(D.prototype);Ib.prototype.constructor=Ib;ee.prototype=Object.create(G.prototype);ee.prototype.constructor=ee;Vc.prototype=Object.create(D.prototype);Vc.prototype.constructor=Vc;fe.prototype=Object.create(G.prototype);fe.prototype.constructor=fe;Wc.prototype=Object.create(D.prototype);Wc.prototype.constructor= +Wc;fc.prototype=Object.create(G.prototype);fc.prototype.constructor=fc;fc.prototype.toJSON=function(){var a=G.prototype.toJSON.call(this);return Sh(this.parameters.shapes,a)};gc.prototype=Object.create(D.prototype);gc.prototype.constructor=gc;gc.prototype.toJSON=function(){var a=D.prototype.toJSON.call(this);return Sh(this.parameters.shapes,a)};Xc.prototype=Object.create(D.prototype);Xc.prototype.constructor=Xc;hc.prototype=Object.create(G.prototype);hc.prototype.constructor=hc;rb.prototype=Object.create(D.prototype); +rb.prototype.constructor=rb;ge.prototype=Object.create(hc.prototype);ge.prototype.constructor=ge;he.prototype=Object.create(rb.prototype);he.prototype.constructor=he;ie.prototype=Object.create(G.prototype);ie.prototype.constructor=ie;Yc.prototype=Object.create(D.prototype);Yc.prototype.constructor=Yc;var Ba=Object.freeze({WireframeGeometry:Mc,ParametricGeometry:Qd,ParametricBufferGeometry:Nc,TetrahedronGeometry:Sd,TetrahedronBufferGeometry:Oc,OctahedronGeometry:Td,OctahedronBufferGeometry:bc,IcosahedronGeometry:Ud, +IcosahedronBufferGeometry:Pc,DodecahedronGeometry:Vd,DodecahedronBufferGeometry:Qc,PolyhedronGeometry:Rd,PolyhedronBufferGeometry:pa,TubeGeometry:Wd,TubeBufferGeometry:cc,TorusKnotGeometry:Xd,TorusKnotBufferGeometry:Rc,TorusGeometry:Yd,TorusBufferGeometry:Sc,TextGeometry:ce,TextBufferGeometry:Uc,SphereGeometry:de,SphereBufferGeometry:Ib,RingGeometry:ee,RingBufferGeometry:Vc,PlaneGeometry:Fd,PlaneBufferGeometry:$b,LatheGeometry:fe,LatheBufferGeometry:Wc,ShapeGeometry:fc,ShapeBufferGeometry:gc,ExtrudeGeometry:ec, +ExtrudeBufferGeometry:eb,EdgesGeometry:Xc,ConeGeometry:ge,ConeBufferGeometry:he,CylinderGeometry:hc,CylinderBufferGeometry:rb,CircleGeometry:ie,CircleBufferGeometry:Yc,BoxGeometry:Cc,BoxBufferGeometry:Bb});ic.prototype=Object.create(Q.prototype);ic.prototype.constructor=ic;ic.prototype.isShadowMaterial=!0;ic.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);return this};Zc.prototype=Object.create(va.prototype);Zc.prototype.constructor=Zc;Zc.prototype.isRawShaderMaterial= +!0;fb.prototype=Object.create(Q.prototype);fb.prototype.constructor=fb;fb.prototype.isMeshStandardMaterial=!0;fb.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity; +this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth= +a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};jc.prototype=Object.create(fb.prototype);jc.prototype.constructor=jc;jc.prototype.isMeshPhysicalMaterial=!0;jc.prototype.copy=function(a){fb.prototype.copy.call(this,a);this.defines={STANDARD:"",PHYSICAL:""};this.reflectivity=a.reflectivity;this.clearcoat=a.clearcoat;this.clearcoatRoughness= +a.clearcoatRoughness;this.sheen=a.sheen?(this.sheen||new J).copy(a.sheen):null;this.clearcoatNormalMap=a.clearcoatNormalMap;this.clearcoatNormalScale.copy(a.clearcoatNormalScale);this.transparency=a.transparency;return this};Ra.prototype=Object.create(Q.prototype);Ra.prototype.constructor=Ra;Ra.prototype.isMeshPhongMaterial=!0;Ra.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap= +a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap= +a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};kc.prototype=Object.create(Ra.prototype);kc.prototype.constructor=kc;kc.prototype.isMeshToonMaterial= +!0;kc.prototype.copy=function(a){Ra.prototype.copy.call(this,a);this.gradientMap=a.gradientMap;return this};lc.prototype=Object.create(Q.prototype);lc.prototype.constructor=lc;lc.prototype.isMeshNormalMaterial=!0;lc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale; +this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};mc.prototype=Object.create(Q.prototype);mc.prototype.constructor=mc;mc.prototype.isMeshLambertMaterial=!0;mc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap= +a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning; +this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};nc.prototype=Object.create(Q.prototype);nc.prototype.constructor=nc;nc.prototype.isMeshMatcapMaterial=!0;nc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.defines={MATCAP:""};this.color.copy(a.color);this.matcap=a.matcap;this.map=a.map;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap; +this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.alphaMap=a.alphaMap;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};oc.prototype=Object.create(Y.prototype);oc.prototype.constructor=oc;oc.prototype.isLineDashedMaterial=!0;oc.prototype.copy=function(a){Y.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};var uk=Object.freeze({ShadowMaterial:ic,SpriteMaterial:Hb, +RawShaderMaterial:Zc,ShaderMaterial:va,PointsMaterial:Qa,MeshPhysicalMaterial:jc,MeshStandardMaterial:fb,MeshPhongMaterial:Ra,MeshToonMaterial:kc,MeshNormalMaterial:lc,MeshLambertMaterial:mc,MeshDepthMaterial:Eb,MeshDistanceMaterial:Fb,MeshBasicMaterial:ya,MeshMatcapMaterial:nc,LineDashedMaterial:oc,LineBasicMaterial:Y,Material:Q}),Z={arraySlice:function(a,b,c){return Z.isTypedArray(a)?new a.constructor(a.subarray(b,void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&& +a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,b,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,l=0;l!==b;++l)e[g++]=a[h+l];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!== +f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];while(void 0!==f)}}}};Object.assign(Ha.prototype,{evaluate:function(a){var b=this.parameterPositions,c=this._cachedIndex,d=b[c],e=b[c-1];a:{b:{c:{d:if(!(a< +d)){for(var f=c+2;;){if(void 0===d){if(a=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=this.getValueSize(),this.times=aa.arraySlice(c,e,f),this.values=aa.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times; -b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: Track is empty.",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&aa.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: Value is not a valid number.", -this,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=this.getValueSize(),d=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;gg)e=a+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(),c=Math.acos(O.clamp(d[k-1].dot(d[k]),-1,1)),e[k].applyMatrix4(h.makeRotationAxis(g,c))),f[k].crossVectors(d[k],e[k]);if(!0===b)for(c=Math.acos(O.clamp(e[0].dot(e[a]),-1,1)),c/=a,0d;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>k&&(k=e);af.initNonuniformCatmullRom(f.x,g.x,h.x,c.x,d,e,k);bf.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,k);cf.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d,e,k)}else"catmullrom"===this.curveType&&(af.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),bf.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),cf.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(af.calc(a), -bf.calc(a),cf.calc(a));return b};wa.prototype.copy=function(a){J.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bc.length-2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set(Uf(d,e.x,f.x,g.x,c.x),Uf(d,e.y,f.y,g.y,c.y));return b};Ra.prototype.copy=function(a){J.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths(); -return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},getCurveLengths:function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;cNumber.EPSILON){if(0>m&&(g=b[f],k=-k,h=b[e],m=-m),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=m*(a.x-g.x)-k*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=h.x))return!0}return d}var e=eb.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new tb;h.curves=g.curves; -b.push(h);return b}var k=!e(f[0].getPoints());k=a?!k:k;h=[];var m=[],l=[],n=0;m[n]=void 0;l[n]=[];for(var u=0,t=f.length;ul.opacity&&(l.transparent=!0);d.setTextures(k);return d.parse(l)}}()});var le,Pe={getContext:function(){void 0===le&&(le=new (window.AudioContext||window.webkitAudioContext));return le},setContext:function(a){le=a}};Object.assign(Ke.prototype,{load:function(a,b,c,d){var e=new Na(this.manager);e.setResponseType("arraybuffer");e.setPath(this.path);e.load(a,function(a){a=a.slice(0);Pe.getContext().decodeAudioData(a,function(a){b(a)})}, -c,d)},setPath:function(a){this.path=a;return this}});Object.assign(de.prototype,{isSphericalHarmonics3:!0,set:function(a){for(var b=0;9>b;b++)this.coefficients[b].copy(a[b]);return this},zero:function(){for(var a=0;9>a;a++)this.coefficients[a].set(0,0,0);return this},getAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.282095);b.addScale(e[1],.488603*d);b.addScale(e[2],.488603*a);b.addScale(e[3],.488603*c);b.addScale(e[4],1.092548*c*d);b.addScale(e[5],1.092548* -d*a);b.addScale(e[6],.315392*(3*a*a-1));b.addScale(e[7],1.092548*c*a);b.addScale(e[8],.546274*(c*c-d*d));return b},getIrradianceAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.886227);b.addScale(e[1],1.023328*d);b.addScale(e[2],1.023328*a);b.addScale(e[3],1.023328*c);b.addScale(e[4],.858086*c*d);b.addScale(e[5],.858086*d*a);b.addScale(e[6],.743125*a*a-.247708);b.addScale(e[7],.858086*c*a);b.addScale(e[8],.429043*(c*c-d*d));return b},add:function(a){for(var b= -0;9>b;b++)this.coefficients[b].add(a.coefficients[b]);return this},scale:function(a){for(var b=0;9>b;b++)this.coefficients[b].multiplyScalar(a);return this},lerp:function(a,b){for(var c=0;9>c;c++)this.coefficients[c].lerp(a.coefficients[c],b);return this},equals:function(a){for(var b=0;9>b;b++)if(!this.coefficients[b].equals(a.coefficients[b]))return!1;return!0},copy:function(a){return this.set(a.coefficients)},clone:function(){return(new this.constructor).copy(this)},fromArray:function(a){for(var b= -this.coefficients,c=0;9>c;c++)b[c].fromArray(a,3*c);return this},toArray:function(){for(var a=[],b=this.coefficients,c=0;9>c;c++)b[c].toArray(a,3*c);return a}});Object.assign(de,{getBasisAt:function(a,b){var c=a.x,d=a.y;a=a.z;b[0]=.282095;b[1]=.488603*d;b[2]=.488603*a;b[3]=.488603*c;b[4]=1.092548*c*d;b[5]=1.092548*d*a;b[6]=.315392*(3*a*a-1);b[7]=1.092548*c*a;b[8]=.546274*(c*c-d*d)}});Ta.prototype=Object.assign(Object.create(R.prototype),{constructor:Ta,isLightProbe:!0,copy:function(a){R.prototype.copy.call(this, -a);this.sh.copy(a.sh);this.intensity=a.intensity;return this},toJSON:function(a){return R.prototype.toJSON.call(this,a)}});Le.prototype=Object.assign(Object.create(Ta.prototype),{constructor:Le,isHemisphereLightProbe:!0,copy:function(a){Ta.prototype.copy.call(this,a);return this},toJSON:function(a){return Ta.prototype.toJSON.call(this,a)}});Me.prototype=Object.assign(Object.create(Ta.prototype),{constructor:Me,isAmbientLightProbe:!0,copy:function(a){Ta.prototype.copy.call(this,a);return this},toJSON:function(a){return Ta.prototype.toJSON.call(this, -a)}});Object.assign(Wf.prototype,{update:function(){var a,b,c,d,e,f,g,h,k=new Q,l=new Q;return function(m){if(a!==this||b!==m.focus||c!==m.fov||d!==m.aspect*this.aspect||e!==m.near||f!==m.far||g!==m.zoom||h!==this.eyeSep){a=this;b=m.focus;c=m.fov;d=m.aspect*this.aspect;e=m.near;f=m.far;g=m.zoom;var n=m.projectionMatrix.clone();h=this.eyeSep/2;var r=h*e/b,t=e*Math.tan(O.DEG2RAD*c*.5)/g;l.elements[12]=-h;k.elements[12]=h;var q=-t*d+r;var v=t*d+r;n.elements[0]=2*e/(v-q);n.elements[8]=(v+q)/(v-q);this.cameraL.projectionMatrix.copy(n); -q=-t*d-r;v=t*d-r;n.elements[0]=2*e/(v-q);n.elements[8]=(v+q)/(v-q);this.cameraR.projectionMatrix.copy(n)}this.cameraL.matrixWorld.copy(m.matrixWorld).multiply(l);this.cameraR.matrixWorld.copy(m.matrixWorld).multiply(k)}}()});Object.assign(Ne.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta(); -return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});Oe.prototype=Object.assign(Object.create(G.prototype),{constructor:Oe,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination), -this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a,this.context.currentTime,.01);return this}, -updateMatrixWorld:function(){var a=new n,b=new da,c=new n,d=new n,e=new Ne;return function(f){G.prototype.updateMatrixWorld.call(this,f);f=this.context.listener;var g=this.up;this.timeDelta=e.getDelta();this.matrixWorld.decompose(a,b,c);d.set(0,0,-1).applyQuaternion(b);if(f.positionX){var h=this.context.currentTime+this.timeDelta;f.positionX.linearRampToValueAtTime(a.x,h);f.positionY.linearRampToValueAtTime(a.y,h);f.positionZ.linearRampToValueAtTime(a.z,h);f.forwardX.linearRampToValueAtTime(d.x,h); -f.forwardY.linearRampToValueAtTime(d.y,h);f.forwardZ.linearRampToValueAtTime(d.z,h);f.upX.linearRampToValueAtTime(g.x,h);f.upY.linearRampToValueAtTime(g.y,h);f.upZ.linearRampToValueAtTime(g.z,h)}else f.setPosition(a.x,a.y,a.z),f.setOrientation(d.x,d.y,d.z,g.x,g.y,g.z)}}()});uc.prototype=Object.assign(Object.create(G.prototype),{constructor:uc,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this}, +a)for(var b=this.times,c=0,d=b.length;c!==d;++c)b[c]*=a;return this},trim:function(a,b){for(var c=this.times,d=c.length,e=0,f=d-1;e!==d&&c[e]b;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=this.getValueSize(),this.times=Z.arraySlice(c,e,f),this.values=Z.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times; +b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: Track is empty.",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&Z.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: Value is not a valid number.", +this,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=this.getValueSize(),d=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;gg)e=a+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(),c=Math.acos(O.clamp(d[l-1].dot(d[l]),-1,1)),e[l].applyMatrix4(h.makeRotationAxis(g,c))),f[l].crossVectors(d[l], +e[l]);if(!0===b)for(c=Math.acos(O.clamp(e[0].dot(e[a]),-1,1)),c/=a,0d;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>l&&(l=e);Wg.initNonuniformCatmullRom(f.x,g.x,h.x,c.x,d,e,l);Xg.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,l);Yg.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d, +e,l)}else"catmullrom"===this.curveType&&(Wg.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),Xg.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),Yg.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(Wg.calc(a),Xg.calc(a),Yg.calc(a));return b};sa.prototype.copy=function(a){F.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bc.length-2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set(Uh(d,e.x,f.x,g.x, +c.x),Uh(d,e.y,f.y,g.y,c.y));return b};Va.prototype.copy=function(a){F.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths();return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},getCurveLengths:function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[], +b=0,c=0,d=this.curves.length;cNumber.EPSILON){if(0>k&&(g=b[f],l=-l,h=b[e],k=-k),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=k*(a.x-g.x)-l*(a.y-g.y);if(0===e)return!0; +0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=h.x))return!0}return d}var e=qb.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new Jb;h.curves=g.curves;b.push(h);return b}var l=!e(f[0].getPoints());l=a?!l:l;h=[];var k=[],n=[],u=0;k[u]=void 0;n[u]=[];for(var r=0,q=f.length;rb;b++)this.coefficients[b].copy(a[b]);return this},zero:function(){for(var a=0;9>a;a++)this.coefficients[a].set(0, +0,0);return this},getAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.282095);b.addScale(e[1],.488603*d);b.addScale(e[2],.488603*a);b.addScale(e[3],.488603*c);b.addScale(e[4],1.092548*c*d);b.addScale(e[5],1.092548*d*a);b.addScale(e[6],.315392*(3*a*a-1));b.addScale(e[7],1.092548*c*a);b.addScale(e[8],.546274*(c*c-d*d));return b},getIrradianceAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.886227);b.addScale(e[1], +1.023328*d);b.addScale(e[2],1.023328*a);b.addScale(e[3],1.023328*c);b.addScale(e[4],.858086*c*d);b.addScale(e[5],.858086*d*a);b.addScale(e[6],.743125*a*a-.247708);b.addScale(e[7],.858086*c*a);b.addScale(e[8],.429043*(c*c-d*d));return b},add:function(a){for(var b=0;9>b;b++)this.coefficients[b].add(a.coefficients[b]);return this},scale:function(a){for(var b=0;9>b;b++)this.coefficients[b].multiplyScalar(a);return this},lerp:function(a,b){for(var c=0;9>c;c++)this.coefficients[c].lerp(a.coefficients[c], +b);return this},equals:function(a){for(var b=0;9>b;b++)if(!this.coefficients[b].equals(a.coefficients[b]))return!1;return!0},copy:function(a){return this.set(a.coefficients)},clone:function(){return(new this.constructor).copy(this)},fromArray:function(a,b){void 0===b&&(b=0);for(var c=this.coefficients,d=0;9>d;d++)c[d].fromArray(a,b+3*d);return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);for(var c=this.coefficients,d=0;9>d;d++)c[d].toArray(a,b+3*d);return a}});Object.assign(lf, +{getBasisAt:function(a,b){var c=a.x,d=a.y;a=a.z;b[0]=.282095;b[1]=.488603*d;b[2]=.488603*a;b[3]=.488603*c;b[4]=1.092548*c*d;b[5]=1.092548*d*a;b[6]=.315392*(3*a*a-1);b[7]=1.092548*c*a;b[8]=.546274*(c*c-d*d)}});Xa.prototype=Object.assign(Object.create(V.prototype),{constructor:Xa,isLightProbe:!0,copy:function(a){V.prototype.copy.call(this,a);this.sh.copy(a.sh);this.intensity=a.intensity;return this},toJSON:function(a){return V.prototype.toJSON.call(this,a)}});tg.prototype=Object.assign(Object.create(Xa.prototype), +{constructor:tg,isHemisphereLightProbe:!0,copy:function(a){Xa.prototype.copy.call(this,a);return this},toJSON:function(a){return Xa.prototype.toJSON.call(this,a)}});ug.prototype=Object.assign(Object.create(Xa.prototype),{constructor:ug,isAmbientLightProbe:!0,copy:function(a){Xa.prototype.copy.call(this,a);return this},toJSON:function(a){return Xa.prototype.toJSON.call(this,a)}});var yi=new P,zi=new P;Object.assign(Vh.prototype,{update:function(a){var b=this._cache;if(b.focus!==a.focus||b.fov!==a.fov|| +b.aspect!==a.aspect*this.aspect||b.near!==a.near||b.far!==a.far||b.zoom!==a.zoom||b.eyeSep!==this.eyeSep){b.focus=a.focus;b.fov=a.fov;b.aspect=a.aspect*this.aspect;b.near=a.near;b.far=a.far;b.zoom=a.zoom;b.eyeSep=this.eyeSep;var c=a.projectionMatrix.clone(),d=b.eyeSep/2,e=d*b.near/b.focus,f=b.near*Math.tan(O.DEG2RAD*b.fov*.5)/b.zoom;zi.elements[12]=-d;yi.elements[12]=d;d=-f*b.aspect+e;var g=f*b.aspect+e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraL.projectionMatrix.copy(c);d= +-f*b.aspect-e;g=f*b.aspect-e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraR.projectionMatrix.copy(c)}this.cameraL.matrixWorld.copy(a.matrixWorld).multiply(zi);this.cameraR.matrixWorld.copy(a.matrixWorld).multiply(yi)}});Object.assign(vg.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta(); +return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});var uc=new n,Ai=new na,wk=new n,vc=new n;wg.prototype=Object.assign(Object.create(B.prototype),{constructor:wg,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination), +this.gain.connect(this.context.destination),this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a, +this.context.currentTime,.01);return this},updateMatrixWorld:function(a){B.prototype.updateMatrixWorld.call(this,a);a=this.context.listener;var b=this.up;this.timeDelta=this._clock.getDelta();this.matrixWorld.decompose(uc,Ai,wk);vc.set(0,0,-1).applyQuaternion(Ai);if(a.positionX){var c=this.context.currentTime+this.timeDelta;a.positionX.linearRampToValueAtTime(uc.x,c);a.positionY.linearRampToValueAtTime(uc.y,c);a.positionZ.linearRampToValueAtTime(uc.z,c);a.forwardX.linearRampToValueAtTime(vc.x,c); +a.forwardY.linearRampToValueAtTime(vc.y,c);a.forwardZ.linearRampToValueAtTime(vc.z,c);a.upX.linearRampToValueAtTime(b.x,c);a.upY.linearRampToValueAtTime(b.y,c);a.upZ.linearRampToValueAtTime(b.z,c)}else a.setPosition(uc.x,uc.y,uc.z),a.setOrientation(vc.x,vc.y,vc.z,b.x,b.y,b.z)}});dd.prototype=Object.assign(Object.create(B.prototype),{constructor:dd,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this}, setMediaElementSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaNode";this.source=this.context.createMediaElementSource(a);this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},play:function(){if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing.");else if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else{var a=this.context.createBufferSource(); -a.buffer=this.buffer;a.loop=this.loop;a.onended=this.onEnded.bind(this);this.startTime=this.context.currentTime;a.start(this.startTime,this.offset);this.isPlaying=!0;this.source=a;this.setDetune(this.detune);this.setPlaybackRate(this.playbackRate);return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return!0===this.isPlaying&&(this.source.stop(),this.source.onended=null,this.offset+=(this.context.currentTime- +a.buffer=this.buffer;a.loop=this.loop;a.onended=this.onEnded.bind(this);this.startTime=this.context.currentTime;a.start(this.startTime,this.offset,this.duration);this.isPlaying=!0;this.source=a;this.setDetune(this.detune);this.setPlaybackRate(this.playbackRate);return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return!0===this.isPlaying&&(this.source.stop(),this.source.onended=null,this.offset+=(this.context.currentTime- this.startTime)*this.playbackRate,this.isPlaying=!1),this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.source.stop(),this.source.onended=null,this.offset=0,this.isPlaying=!1,this},connect:function(){if(0d&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){da.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d, -e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}});Object.assign(Xf.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_, -c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(qa,{Composite:Xf,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new qa.Composite(a,b,c):new qa(a,b,c)},sanitizeNodeName:function(){var a=/[\[\]\.:\/]/g;return function(b){return b.replace(/\s/g,"_").replace(a,"")}}(),parseTrackName:function(){var a="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]",b=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]");a=/(WCOD+)?/.source.replace("WCOD",a);var c=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC", -"[^\\[\\]\\.:\\/]"),d=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"),e=new RegExp("^"+b+a+c+d+"$"),f=["material","materials","bones"];return function(a){var b=e.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&&b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!==c){var d=b.nodeName.substring(c+1);-1!==f.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName= -d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b}}(),findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a;if(a.skeleton){var c=a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c=0;c=b){var n=b++,p=a[n];c[p.uuid]=l;a[l]=p;c[k]=n;a[n]=h;h=0;for(k=e;h!==k;++h){p= -d[h];var u=p[l];p[l]=p[n];p[n]=u}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k=arguments[g].uuid,l=d[k];if(void 0!==l)if(delete d[k],ld&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d= +0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){na.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}});var yk=/[\[\]\.:\/]/g,zk="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]",Ak=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]"),Bk=/(WCOD+)?/.source.replace("WCOD",zk),Ck=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC","[^\\[\\]\\.:\\/]"),Dk=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"),Ek=new RegExp("^"+Ak+Bk+ +Ck+Dk+"$"),Fk=["material","materials","bones"];Object.assign(Wh.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_, +c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(ma,{Composite:Wh,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new ma.Composite(a,b,c):new ma(a,b,c)},sanitizeNodeName:function(a){return a.replace(/\s/g,"_").replace(yk,"")},parseTrackName:function(a){var b=Ek.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&&b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!== +c){var d=b.nodeName.substring(c+1);-1!==Fk.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName=d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b},findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a;if(a.skeleton){var c=a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c=0;c=b){var n=b++,u=a[n];c[u.uuid]=m;a[m]=u;c[k]=n;a[n]=h;h=0;for(k=e;h!==k;++h){u=d[h];var r=u[m];u[m]=u[n];u[n]=r}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k=arguments[g].uuid,m=d[k];if(void 0!==m)if(delete d[k],mb||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){b=this.timeScale;var c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0]; b*=d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0:this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a,c=this._clip.duration,d=this.loop,e=this._loopCount,f=2202===d;if(0===a)return-1===e?b:f&&1===(e&1)?c-b:b;if(2200===d)a:{if(-1===e&&(this._loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else{this.time=b;break a}this.clampWhenFinished?this.paused=!0:this.enabled=!1;this.time=b;this._mixer.dispatchEvent({type:"finished", action:this,direction:0>a?-1:1})}else{-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,f)):this._setEndings(0===this.repetitions,!0,f));if(b>=c||0>b){d=Math.floor(b/c);b-=c*d;e+=Math.abs(d);var g=this.repetitions-e;0>=g?(this.clampWhenFinished?this.paused=!0:this.enabled=!1,this.time=b=0a,this._setEndings(a,!a,f)):this._setEndings(!1,!1,f),this._loopCount=e,this.time=b,this._mixer.dispatchEvent({type:"loop", action:this,loopDelta:d}))}else this.time=b;if(f&&1===(e&1))return c-b}return b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd=b?this.zeroSlopeAtEnd?2401:2400:2402)},_scheduleFading:function(a,b,c){var d=this._mixer,e=d.time,f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]= -c;return this}});Te.prototype=Object.assign(Object.create(na.prototype),{constructor:Te,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName,k=h[g];void 0===k&&(k={},h[g]=k);for(h=0;h!==e;++h){var l=d[h],n=l.name,p=k[n];if(void 0===p){p=f[h];if(void 0!==p){null===p._cacheIndex&&(++p.referenceCount,this._addInactiveBinding(p,g,n));continue}p=new Se(qa.create(c,n,b&&b._propertyBindings[h].binding.parsedPath), -l.ValueTypeName,l.getValueSize());++p.referenceCount;this._addInactiveBinding(p,g,n)}f[h]=p;a[h].resultBuffer=p.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}}, +c;return this}});Bg.prototype=Object.assign(Object.create(xa.prototype),{constructor:Bg,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName,k=h[g];void 0===k&&(k={},h[g]=k);for(h=0;h!==e;++h){var m=d[h],n=m.name,u=k[n];if(void 0===u){u=f[h];if(void 0!==u){null===u._cacheIndex&&(++u.referenceCount,this._addInactiveBinding(u,g,n));continue}u=new Ag(ma.create(c,n,b&&b._propertyBindings[h].binding.parsedPath), +m.ValueTypeName,m.getValueSize());++u.referenceCount;this._addInactiveBinding(u,g,n)}f[h]=u;a[h].resultBuffer=u.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}}, _deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions=[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length}, get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}},_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&athis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y},getParameter:function(a, -b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"),b=new D);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new D);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new D; -return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var me,Ed;Object.assign(Xe.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)}, -copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){void 0===a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)}, -at:function(a,b){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b=new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(a,b){void 0===me&&(me=new n,Ed=new n);me.subVectors(a,this.start);Ed.subVectors(this.end,this.start);a=Ed.dot(Ed);a=Ed.dot(me)/a;b&&(a=O.clamp(a,0,1));return a},closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"), -c=new n);return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a);this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});xd.prototype=Object.create(G.prototype);xd.prototype.constructor=xd;xd.prototype.isImmediateRenderObject=!0;yd.prototype=Object.create(U.prototype);yd.prototype.constructor=yd;yd.prototype.update=function(){var a=new n,b=new n,c=new ja;return function(){var d=["a","b", -"c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var e=this.object.matrixWorld,f=this.geometry.attributes.position,g=this.object.geometry;if(g&&g.isGeometry)for(var h=g.vertices,k=g.faces,l=g=0,n=k.length;lMath.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);G.prototype.updateMatrixWorld.call(this,a)};var he,Ye;ib.prototype=Object.create(G.prototype);ib.prototype.constructor=ib;ib.prototype.setDirection=function(){var a=new n,b;return function(c){.99999c.y?this.quaternion.set(1, -0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,b))}}();ib.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};ib.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)};ib.prototype.copy=function(a){G.prototype.copy.call(this,a,!1);this.line.copy(a.line); -this.cone.copy(a.cone);return this};ib.prototype.clone=function(){return(new this.constructor).copy(this)};Dd.prototype=Object.create(U.prototype);Dd.prototype.constructor=Dd;J.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(J.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(gb.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead."); -a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){console.warn("THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){console.warn("THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");for(var b=new N,c=0,d=a.length;cthis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"), +b=new v);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new v);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return Ci.copy(a).clamp(this.min,this.max).sub(a).length()},intersect:function(a){this.min.max(a.min); +this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var Di=new n,Kf=new n;Object.assign(Fg.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){void 0=== +a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b= +new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(a,b){Di.subVectors(a,this.start);Kf.subVectors(this.end,this.start);a=Kf.dot(Kf);a=Kf.dot(Di)/a;b&&(a=O.clamp(a,0,1));return a},closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"),c=new n);return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a); +this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});oe.prototype=Object.create(B.prototype);oe.prototype.constructor=oe;oe.prototype.isImmediateRenderObject=!0;var mb=new n,Ab=new n,bh=new ta,Gk=["a","b","c"];pe.prototype=Object.create(R.prototype);pe.prototype.constructor=pe;pe.prototype.update=function(){this.object.updateMatrixWorld(!0);bh.getNormalMatrix(this.object.matrixWorld);var a=this.object.matrixWorld,b=this.geometry.attributes.position, +c=this.object.geometry;if(c&&c.isGeometry)for(var d=c.vertices,e=c.faces,f=c=0,g=e.length;f +Math.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);B.prototype.updateMatrixWorld.call(this,a)};var Ki=new n,qf,Gg;ub.prototype=Object.create(B.prototype);ub.prototype.constructor=ub;ub.prototype.setDirection=function(a){.99999a.y?this.quaternion.set(1,0,0,0):(Ki.set(a.z,0,-a.x).normalize(),this.quaternion.setFromAxisAngle(Ki,Math.acos(a.y)))};ub.prototype.setLength=function(a, +b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};ub.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)};ub.prototype.copy=function(a){B.prototype.copy.call(this,a,!1);this.line.copy(a.line);this.cone.copy(a.cone);return this};ub.prototype.clone=function(){return(new this.constructor).copy(this)};ue.prototype=Object.create(R.prototype); +ue.prototype.constructor=ue;F.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(F.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(sb.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){console.warn("THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead."); +a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){console.warn("THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");for(var b=new G,c=0,d=a.length;corg.treblereel.gwt.three4g three4g-demo - 0.106-SNAPSHOT + 0.108-SNAPSHOT war THREE4G:DEMO @@ -15,7 +15,7 @@ 1.5.11 1.1.0 UTF-8 - 0.107 + 0.108 diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/Attachable.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/Attachable.java index 22a05cd7..883e1001 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/Attachable.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/Attachable.java @@ -82,7 +82,7 @@ public void doDetach() { window.removeEventListener("resize", onResize); } - private void detachControls() { + protected void detachControls() { if (orbitControls != null) { orbitControls.dispose(); } @@ -97,7 +97,7 @@ private void detachControls() { } } - private void detachGui() { + protected void detachGui() { if (gui != null) { gui.getDomElement().parentNode.removeChild(gui.getDomElement()); gui = null; diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/animation/WebGlAnimationKeyframesJson.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/animation/WebGlAnimationKeyframesJson.java index 335ae647..d8de9437 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/animation/WebGlAnimationKeyframesJson.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/animation/WebGlAnimationKeyframesJson.java @@ -1,6 +1,6 @@ package org.treblereel.gwt.three4g.demo.client.local.examples.animation; -import com.google.gwt.animation.client.AnimationScheduler; +import elemental2.dom.DomGlobal; import org.treblereel.gwt.three4g.animation.AnimationClip; import org.treblereel.gwt.three4g.animation.AnimationMixer; import org.treblereel.gwt.three4g.cameras.PerspectiveCamera; @@ -18,75 +18,72 @@ import org.treblereel.gwt.three4g.objects.Group; import org.treblereel.gwt.three4g.scenes.Scene; - /** * @author Dmitrii Tikhomirov Created by treblereel on 3/16/18. */ public class WebGlAnimationKeyframesJson extends Attachable { - public static final String name = "animation / keyframes / json"; - private AnimationMixer mixer; - private String json = "json/pump/pump.json"; - - private Clock clock = new Clock(); + public static final String name = "animation / keyframes / json"; + private AnimationMixer mixer; + private String json = "json/pump/pump.json"; - public WebGlAnimationKeyframesJson() { - setupWebGLRenderer(renderer); + private Clock clock = new Clock(); - scene = new Scene(); + public WebGlAnimationKeyframesJson() { + setupWebGLRenderer(renderer); - GridHelper grid = new GridHelper(20, 20, new Color(0x888888), new Color(0x888888)); - grid.position.set(0f, -1.1f, 0f); - scene.add(grid); + scene = new Scene(); - camera = new PerspectiveCamera(40f, aspect, 1f, 100f); - camera.position.set(-5.00f, 3.43f, 11.31f); - camera.lookAt(new Vector3(-1.22f, 2.18f, 4.58f)); - scene.add(new AmbientLight(0x404040)); + GridHelper grid = new GridHelper(20, 20, new Color(0x888888), new Color(0x888888)); + grid.position.set(0f, -1.1f, 0f); + scene.add(grid); - PointLight pointLight = new PointLight(0xffffff, 1f); - pointLight.position.copy(camera.position); - scene.add(pointLight); + camera = new PerspectiveCamera(40f, aspect, 1f, 100f); + camera.position.set(-5.00f, 3.43f, 11.31f); + camera.lookAt(new Vector3(-1.22f, 2.18f, 4.58f)); + scene.add(new AmbientLight(0x404040)); - new ObjectLoader().load(json, (OnLoadCallback) group -> { - scene.add(group); - AnimationClip[] clips = group.getProperty("animations"); - mixer = new AnimationMixer(group); - mixer.clipAction(clips[0]).play(); - }); + PointLight pointLight = new PointLight(0xffffff, 1f); + pointLight.position.copy(camera.position); + scene.add(pointLight); + new ObjectLoader().load(json, (OnLoadCallback) group -> { + scene.add(group); + AnimationClip[] clips = group.getProperty("animations"); + mixer = new AnimationMixer(group); + mixer.clipAction(clips[0]).play(); + }); + } - } + public void doAttachScene() { + root.appendChild(renderer.domElement); + onWindowResize(); + animate(); + } - public void doAttachScene() { - root.appendChild(renderer.domElement); - onWindowResize(); - animate(); - } + @Override + protected void doAttachInfo() { + AppSetup.infoDiv.show().setHrefToInfo("http://threejs.org").setTextContentToInfo("three.js") + .setTextToDesc(" webgl - animation - keyframes - json"); + } - @Override - protected void doAttachInfo() { - AppSetup.infoDiv.show().setHrefToInfo("http://threejs.org").setTextContentToInfo("three.js") - .setTextToDesc(" webgl - animation - keyframes - json"); - } + private void render() { + if (mixer != null) { + mixer.update(clock.getDelta()); + renderer.render(scene, camera); + } + } - private void render() { - if (mixer != null) { - mixer.update(clock.getDelta()); + private void animate() { + DomGlobal.requestAnimationFrame(timestamp -> { + if (root.parentNode != null) { + StatsProducer.getStats().update(); - renderer.render(scene, camera); + render(); + animate(); + } + }); } - } - - private void animate() { - StatsProducer.getStats().update(); - AnimationScheduler.get().requestAnimationFrame(timestamp -> { - if (root.parentNode != null) { - render(); - animate(); - } - }); - } } diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/animation/WebglAnimationScene.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/animation/WebglAnimationScene.java index a2b2b2d0..b9b8abab 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/animation/WebglAnimationScene.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/animation/WebglAnimationScene.java @@ -1,16 +1,11 @@ package org.treblereel.gwt.three4g.demo.client.local.examples.animation; -import com.google.gwt.animation.client.AnimationScheduler; -import com.google.gwt.json.client.JSONObject; -import elemental2.core.JsObject; import elemental2.dom.DomGlobal; -import jsinterop.base.Js; import org.treblereel.gwt.three4g.InjectJavaScriptFor; import org.treblereel.gwt.three4g.animation.AnimationClip; import org.treblereel.gwt.three4g.animation.AnimationMixer; import org.treblereel.gwt.three4g.cameras.PerspectiveCamera; import org.treblereel.gwt.three4g.core.Clock; -import org.treblereel.gwt.three4g.core.Object3D; import org.treblereel.gwt.three4g.core.PropertyHolder; import org.treblereel.gwt.three4g.demo.client.local.AppSetup; import org.treblereel.gwt.three4g.demo.client.local.Attachable; @@ -115,9 +110,10 @@ protected void doAttachInfo() { } private void animate() { - StatsProducer.getStats().update(); - AnimationScheduler.get().requestAnimationFrame(timestamp -> { + DomGlobal.requestAnimationFrame(timestamp -> { if (root.parentNode != null && mixer != null) { + StatsProducer.getStats().update(); + double delta = clock.getDelta(); mixer.update(delta); orbitControls.update(); diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/controls/MiscControlsPointerlock.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/controls/MiscControlsPointerlock.java index ae217f4a..ffecc706 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/controls/MiscControlsPointerlock.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/controls/MiscControlsPointerlock.java @@ -4,6 +4,7 @@ import com.google.gwt.animation.client.AnimationScheduler; import elemental2.core.JsArray; +import elemental2.dom.DomGlobal; import elemental2.dom.Event; import elemental2.dom.EventListener; import elemental2.dom.HTMLDivElement; @@ -67,6 +68,9 @@ public class MiscControlsPointerlock extends Attachable { public MiscControlsPointerlock() { + DomGlobal.console.log("1"); + + instructions.innerHTML = content; instructions.id = "instructions"; blocker.appendChild(instructions); @@ -80,15 +84,25 @@ public MiscControlsPointerlock() { camera = new PerspectiveCamera(75, aspect, 1, 1000); scene = new Scene(); scene.background = new Color(0xffffff); + DomGlobal.console.log("1.1"); + + scene.fog = new Fog(0xffffff, 0, 750); HemisphereLight light = new HemisphereLight(0xeeeeff, 0x777788, 0.75f); light.position.set(0.5f, 1, 0.75f); + scene.add(light); - controls = new PointerLockControls(camera); + DomGlobal.console.log("1.1.4 "); + + controls = new PointerLockControls(camera, document.body); + DomGlobal.console.log("1.2"); instructions.addEventListener("click", evt -> controls.lock(), false); + DomGlobal.console.log("2"); + + controls.addEventListener("lock", evt -> { instructions.style.display = "none"; blocker.style.display = "none"; @@ -102,6 +116,9 @@ public MiscControlsPointerlock() { scene.add(controls.getObject()); + DomGlobal.console.log("3"); + + raycaster = new Raycaster(new Vector3(), new Vector3(0, -1, 0), 0, 10); // floor BufferGeometry floorGeometry = new PlaneBufferGeometry(2000, 2000, 100, 100); @@ -116,6 +133,7 @@ public MiscControlsPointerlock() { vertex.z += Math.random() * 20 - 10; position.setXYZ(i, vertex.x, vertex.y, vertex.z); } + DomGlobal.console.log("4"); floorGeometry = floorGeometry.toNonIndexed(); // ensure each face has unique vertices @@ -128,6 +146,9 @@ public MiscControlsPointerlock() { colors.push(color.r, color.g, color.b); } + + DomGlobal.console.log("5"); + floorGeometry.addAttribute("color", new Float32BufferAttribute(colors, 3)); MeshBasicMaterial floorMaterial = new MeshBasicMaterial(); floorMaterial.vertexColors = THREE.VertexColors; @@ -143,6 +164,7 @@ public MiscControlsPointerlock() { colors.push(color.r, color.g, color.b); } boxGeometry.addAttribute("color", new Float32BufferAttribute(colors, 3)); + DomGlobal.console.log("6"); MeshPhongMaterialParameters meshPhongMaterialParameters = new MeshPhongMaterialParameters(); meshPhongMaterialParameters.specular = new Color(0xffffff); @@ -160,6 +182,7 @@ public MiscControlsPointerlock() { objects[i] = box; } + DomGlobal.console.log("7"); setupWebGLRenderer(renderer); renderer.shadowMap.enabled = true; @@ -223,6 +246,7 @@ private void onKeyUp(Event evt) { @Override public void detach() { super.detach(); + blocker.style.display = "none"; blocker.parentNode.removeChild(blocker); document.removeEventListener("keyup", keyup); document.removeEventListener("keydown", keydown); @@ -230,9 +254,9 @@ public void detach() { } private void animate() { - StatsProducer.getStats().update(); AnimationScheduler.get().requestAnimationFrame(timestamp -> { if (root.parentNode != null) { + StatsProducer.getStats().update(); render(); animate(); } @@ -241,6 +265,7 @@ private void animate() { private void render() { if (controls.isLocked) { + DomGlobal.console.log("1111"); raycaster.ray.origin.copy(controls.getObject().position); raycaster.ray.origin.y -= 10; Intersect[] intersections = raycaster.intersectObjects(objects); @@ -280,6 +305,7 @@ private int toInt(boolean value) { @Override protected void doAttachScene() { + blocker.style.display = "block"; root.appendChild(renderer.domElement); onWindowResize(); animate(); diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/lights/WebglLightsSpotlight.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/lights/WebglLightsSpotlight.java index 00b46526..14669889 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/lights/WebglLightsSpotlight.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/lights/WebglLightsSpotlight.java @@ -1,12 +1,11 @@ package org.treblereel.gwt.three4g.demo.client.local.examples.lights; -import com.google.gwt.animation.client.AnimationScheduler; +import elemental2.dom.DomGlobal; import org.treblereel.gwt.datgui4g.GUI; import org.treblereel.gwt.datgui4g.GUIProperty; import org.treblereel.gwt.three4g.InjectJavaScriptFor; import org.treblereel.gwt.three4g.THREE; import org.treblereel.gwt.three4g.cameras.PerspectiveCamera; -import org.treblereel.gwt.three4g.core.Clock; import org.treblereel.gwt.three4g.demo.client.local.AppSetup; import org.treblereel.gwt.three4g.demo.client.local.Attachable; import org.treblereel.gwt.three4g.demo.client.local.utils.StatsProducer; @@ -33,16 +32,13 @@ public class WebglLightsSpotlight extends Attachable { public static final String name = "lights / spotlight"; - private Clock clock = new Clock(); private SpotLight spotLight; private SpotLightHelper lightHelper; private CameraHelper shadowCameraHelper; - + private Scene scene = new Scene(); + private PerspectiveCamera camera; public WebglLightsSpotlight() { - - - scene = new Scene(); camera = new PerspectiveCamera(35, aspect, 1, 1000); camera.position.set(65, 8, -10); @@ -98,14 +94,17 @@ public WebglLightsSpotlight() { orbitControls.target.copy(mesh.position); orbitControls.update(); - renderer = new WebGLRenderer(); - setupWebGLRenderer(renderer); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - buildGui(); } + private void render() { + if (renderer.domElement != null) { + lightHelper.update(); + shadowCameraHelper.update(); + renderer.render(scene, camera); + } + } + private void buildGui() { float intensity = spotLight.intensity; float distance = spotLight.distance; @@ -149,26 +148,36 @@ private void buildGui() { gui.finishAndBuild(); AppSetup.guiDiv.get().appendChild(gui.getDomElement()); - } - @Override public void doAttachScene() { + renderer = new WebGLRenderer(); + setupWebGLRenderer(renderer); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; + root.appendChild(renderer.domElement); onWindowResize(); animate(); } + public void doDetach() { + AppSetup.infoDiv.hide(); + AppSetup.menuDiv.hide(); + detachControls(); + detachGui(); + window.removeEventListener("resize", onResize); + } + @Override protected void doAttachInfo() { AppSetup.infoDiv.show().setHrefToInfo("http://threejs.org").setTextContentToInfo("three.js").setInnetHtml(" - webgl - spotlight by Master James"); - + " href=\"http://master-domain.com\" target=\"_blank\" rel=\"noopener\">Master James"); } private void animate() { - AnimationScheduler.get().requestAnimationFrame(timestamp -> { + DomGlobal.requestAnimationFrame(timestamp -> { if (root.parentNode != null) { StatsProducer.getStats().update(); render(); @@ -176,12 +185,5 @@ private void animate() { } }); } - - private void render() { - lightHelper.update(); - shadowCameraHelper.update(); - renderer.render(scene, camera); - } - } diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/material/Webgl2MaterialsTexture2darray.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/material/Webgl2MaterialsTexture2darray.java index df40534c..f0da03a2 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/material/Webgl2MaterialsTexture2darray.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/material/Webgl2MaterialsTexture2darray.java @@ -1,8 +1,8 @@ package org.treblereel.gwt.three4g.demo.client.local.examples.material; -import elemental2.core.ArrayBuffer; import elemental2.core.Uint8Array; import elemental2.dom.DomGlobal; +import elemental2.dom.File; import elemental2.dom.HTMLCanvasElement; import elemental2.dom.HTMLScriptElement; import elemental2.webgl.WebGLRenderingContext; @@ -102,9 +102,9 @@ public Webgl2MaterialsTexture2darray() { // width 256, height 256, depth 109, 8-bit, zip archived raw data new FileLoader() .setResponseType("arraybuffer") - .load("textures/3d/head256x256x109.zip", new OnLoadCallback() { + .load("textures/3d/head256x256x109.zip", new OnLoadCallback() { @Override - public void onLoad(ArrayBuffer object) { + public void onLoad(File object) { DomGlobal.console.log("onLoad 1 " + object); DomGlobal.console.log("onLoad 2 " + JSON.stringify(object)); diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/material/WebglMaterialsVariationsPhysical.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/material/WebglMaterialsVariationsPhysical.java index e8e8a279..17c57266 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/material/WebglMaterialsVariationsPhysical.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/material/WebglMaterialsVariationsPhysical.java @@ -94,8 +94,8 @@ public void onLoad(CubeTexture hdrCubeMap) { parameters.color = diffuseColor; parameters.metalness = 0; parameters.roughness = 0.5f; - parameters.clearCoat = 1.0f - alpha; - parameters.clearCoatRoughness = 1.0f - beta; + parameters.clearcoat = 1.0f - alpha; + parameters.clearcoatRoughness = 1.0f - beta; parameters.reflectivity = 1.0f - gamma; if (index % 2 == 0) diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/performance/WebglPerformance.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/performance/WebglPerformance.java index b7752ad1..0869543e 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/performance/WebglPerformance.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/performance/WebglPerformance.java @@ -1,15 +1,18 @@ package org.treblereel.gwt.three4g.demo.client.local.examples.performance; -import com.google.gwt.animation.client.AnimationScheduler; -import elemental2.dom.MouseEvent; import java.util.ArrayList; import java.util.List; + +import com.google.gwt.animation.client.AnimationScheduler; +import elemental2.dom.MouseEvent; import jsinterop.base.Js; import org.treblereel.gwt.three4g.cameras.PerspectiveCamera; +import org.treblereel.gwt.three4g.core.BufferGeometry; import org.treblereel.gwt.three4g.demo.client.local.AppSetup; import org.treblereel.gwt.three4g.demo.client.local.Attachable; import org.treblereel.gwt.three4g.demo.client.local.utils.StatsProducer; import org.treblereel.gwt.three4g.loaders.BufferGeometryLoader; +import org.treblereel.gwt.three4g.loaders.OnLoadCallback; import org.treblereel.gwt.three4g.materials.MeshNormalMaterial; import org.treblereel.gwt.three4g.math.Color; import org.treblereel.gwt.three4g.math.Vector2; @@ -29,7 +32,6 @@ public class WebglPerformance extends Attachable { private int windowHalfY = window.innerHeight / 2; private List objects = new ArrayList<>(); - public WebglPerformance() { camera = new PerspectiveCamera(60, aspect, 1, 10000); @@ -38,7 +40,8 @@ public WebglPerformance() { scene.background = new Color(0xffffff); MeshNormalMaterial material = new MeshNormalMaterial(); BufferGeometryLoader loader = new BufferGeometryLoader(); - loader.load("json/suzanne_buffergeometry.json", geometry -> { + + loader.load("json/suzanne_buffergeometry.json", (OnLoadCallback) geometry -> { geometry.computeVertexNormals(); for (int i = 0; i < 5000; i++) { Mesh mesh = new Mesh(geometry, material); @@ -67,19 +70,8 @@ public WebglPerformance() { private void onDocumentMouseMove(MouseEvent event) { event.preventDefault(); - mouse.x = (float)( event.clientX - windowHalfX ) * 10; - mouse.y = (float)( event.clientY - windowHalfY ) * 10; - } - - @Override - public void onWindowResize() { - if (camera != null && renderer != null) { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - camera.aspect = aspect; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); - } + mouse.x = (float) (event.clientX - windowHalfX) * 10; + mouse.y = (float) (event.clientY - windowHalfY) * 10; } public void doAttachScene() { @@ -93,6 +85,17 @@ protected void doAttachInfo() { AppSetup.infoDiv.hide(); } + @Override + public void onWindowResize() { + if (camera != null && renderer != null) { + windowHalfX = window.innerWidth / 2; + windowHalfY = window.innerHeight / 2; + camera.aspect = aspect; + camera.updateProjectionMatrix(); + renderer.setSize(window.innerWidth, window.innerHeight); + } + } + private void animate() { StatsProducer.getStats().update(); AnimationScheduler.get().requestAnimationFrame(timestamp -> { @@ -105,14 +108,14 @@ private void animate() { private void render() { - camera.position.x += ( mouse.x - camera.position.x ) * .05; - camera.position.y += ( - mouse.y - camera.position.y ) * .05; - camera.lookAt( scene.position ); - for ( int i = 0, il = objects.size(); i < il; i ++ ) { + camera.position.x += (mouse.x - camera.position.x) * .05; + camera.position.y += (-mouse.y - camera.position.y) * .05; + camera.lookAt(scene.position); + for (int i = 0, il = objects.size(); i < il; i++) { objects.get(i).rotation.x += 0.01; objects.get(i).rotation.y += 0.02; } - renderer.render( scene, camera ); + renderer.render(scene, camera); } } diff --git a/extensions/pom.xml b/extensions/pom.xml index db619737..80f693be 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -5,7 +5,7 @@ org.treblereel.gwt three4g-parent - 0.108-SNAPSHOT + 0.109-SNAPSHOT .. diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/AssimpJSONLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/AssimpJSONLoader.java index d8087af7..d5477d03 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/AssimpJSONLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/AssimpJSONLoader.java @@ -3,13 +3,13 @@ import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.Three4gElement; import org.treblereel.gwt.three4g.core.PropertyHolder; -import org.treblereel.gwt.three4g.loaders.AbstractLoader; +import org.treblereel.gwt.three4g.loaders.Loader; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; /** @author Dmitrii Tikhomirov Created by treblereel 12/14/18 */ @Three4gElement(paths = "js/loaders/AssimpJSONLoader.js") @JsType(isNative = true, namespace = "THREE") -public class AssimpJSONLoader extends AbstractLoader { +public class AssimpJSONLoader extends Loader { /** * If set, assigns the crossOrigin attribute of the image to the value of crossOrigin, prior to diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/AssimpLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/AssimpLoader.java index 8fb94cc6..13533ff6 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/AssimpLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/AssimpLoader.java @@ -3,13 +3,13 @@ import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.Three4gElement; import org.treblereel.gwt.three4g.core.PropertyHolder; -import org.treblereel.gwt.three4g.loaders.AbstractLoader; +import org.treblereel.gwt.three4g.loaders.Loader; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; /** @author Dmitrii Tikhomirov Created by treblereel 12/14/18 */ @Three4gElement(paths = "js/loaders/AssimpLoader.js") @JsType(isNative = true, namespace = "THREE") -public class AssimpLoader extends AbstractLoader { +public class AssimpLoader extends Loader { /** * If set, assigns the crossOrigin attribute of the image to the value of crossOrigin, prior to diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/ColladaLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/ColladaLoader.java index 9321e2e5..dc5b8020 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/ColladaLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/ColladaLoader.java @@ -3,7 +3,7 @@ import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.Three4gElement; import org.treblereel.gwt.three4g.core.PropertyHolder; -import org.treblereel.gwt.three4g.loaders.AbstractLoader; +import org.treblereel.gwt.three4g.loaders.Loader; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; /** @@ -12,7 +12,7 @@ */ @Three4gElement(paths = "js/loaders/ColladaLoader.js") @JsType(isNative = true, namespace = "THREE") -public class ColladaLoader extends AbstractLoader { +public class ColladaLoader extends Loader { /** * If set, assigns the crossOrigin attribute of the image to the value of crossOrigin, prior to starting the load. Default is anonymous. diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/DRACOLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/DRACOLoader.java index 5ac2cf05..ec84db64 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/DRACOLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/DRACOLoader.java @@ -19,9 +19,9 @@ public DRACOLoader() { } - public static native void setDecoderPath(String path); + public native void setDecoderPath(String path); - public static native void setDecoderConfig(DRACOLoaderDecoderConfig config); + public native void setDecoderConfig(DRACOLoaderDecoderConfig config); public native void load(String url, OnLoadCallback onLoad); diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/FBXLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/FBXLoader.java index 8398aeba..a50a136f 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/FBXLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/FBXLoader.java @@ -3,7 +3,7 @@ import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.Three4gElement; import org.treblereel.gwt.three4g.core.Object3D; -import org.treblereel.gwt.three4g.loaders.AbstractLoader; +import org.treblereel.gwt.three4g.loaders.Loader; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; /** @@ -12,7 +12,7 @@ */ @Three4gElement(paths = {"js/loaders/zlib.js", "js/loaders/FBXLoader.js"}) @JsType(isNative = true, namespace = "THREE") -public class FBXLoader extends AbstractLoader { +public class FBXLoader extends Loader { /** * If set, assigns the crossOrigin attribute of the image to the value of crossOrigin, prior to starting the load. Default is anonymous. diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/GLTFLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/GLTFLoader.java index c71c08ad..3f3f8e6e 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/GLTFLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/GLTFLoader.java @@ -4,7 +4,7 @@ import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.Three4gElement; import org.treblereel.gwt.three4g.core.PropertyHolder; -import org.treblereel.gwt.three4g.loaders.AbstractLoader; +import org.treblereel.gwt.three4g.loaders.Loader; import org.treblereel.gwt.three4g.loaders.OnErrorCallback; import org.treblereel.gwt.three4g.loaders.OnLoadCallback; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; @@ -30,7 +30,7 @@ */ @Three4gElement(paths = "js/loaders/GLTFLoader.js") @JsType(isNative = true, namespace = "THREE") -public class GLTFLoader extends AbstractLoader { +public class GLTFLoader extends Loader { /** * If set, assigns the crossOrigin attribute of the image to the value of crossOrigin, prior to diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/LDrawLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/LDrawLoader.java index 69010cfc..f4496978 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/LDrawLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/LDrawLoader.java @@ -1,8 +1,6 @@ package org.treblereel.gwt.three4g.extensions.loaders; -import elemental2.core.JsObject; import jsinterop.annotations.JsType; -import jsinterop.base.JsPropertyMap; import org.treblereel.gwt.three4g.Three4gElement; import org.treblereel.gwt.three4g.core.Object3D; import org.treblereel.gwt.three4g.loaders.OnErrorCallback; @@ -11,30 +9,34 @@ import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; import org.treblereel.gwt.three4g.materials.Material; -/** @author Dmitrii Tikhomirov Created by treblereel 1/19/19 */ +/** + * @author Dmitrii Tikhomirov Created by treblereel 1/19/19 + */ @Three4gElement(paths = {"js/loaders/LDrawLoader.js"}) @JsType(isNative = true, namespace = "THREE") public class LDrawLoader { public Material[] materials; - public LDrawLoader() {} + public LDrawLoader() { + } - public LDrawLoader(LoadingManager manager) {} + public LDrawLoader(LoadingManager manager) { + } /** * @param url — A string containing the path/URL of the .mpd file. * @param onLoad — A function to be called after loading is successfully completed. The function - * receives loaded DataTexture as an argument. + * receives loaded DataTexture as an argument. */ public native void load(String url, OnLoadCallback onLoad); /** * @param url — A string containing the path/URL of the .mpd file. * @param onLoad — A function to be called after loading is successfully completed. The function - * receives loaded DataTexture as an argument. + * receives loaded DataTexture as an argument. * @param onProgress — A function to be called while the loading is in progress. The argument will - * be the XMLHttpRequest instance, which contains .total and .loaded bytes. + * be the XMLHttpRequest instance, which contains .total and .loaded bytes. */ public native void load( String url, OnLoadCallback onLoad, OnProgressCallback onProgress); @@ -42,11 +44,11 @@ public native void load( /** * @param url — A string containing the path/URL of the .mpd file. * @param onLoad — A function to be called after loading is successfully completed. The function - * receives loaded DataTexture as an argument. + * receives loaded DataTexture as an argument. * @param onProgress — A function to be called while the loading is in progress. The argument will - * be the XMLHttpRequest instance, which contains .total and .loaded bytes. + * be the XMLHttpRequest instance, which contains .total and .loaded bytes. * @param onError — A function to be called if an error occurs during loading. The function - * receives the error as an argument. + * receives the error as an argument. */ public native void load( String url, @@ -63,7 +65,6 @@ public native void load( /** * Set the base path or URL from which to load files. This can be useful if you are loading many * models from the same directory. - * * @param path base path or URL * @return instance of LDrawLoader */ diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/MTLLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/MTLLoader.java index 144f5739..b792b402 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/MTLLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/MTLLoader.java @@ -4,7 +4,7 @@ import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.Three4gElement; import org.treblereel.gwt.three4g.core.PropertyHolder; -import org.treblereel.gwt.three4g.loaders.AbstractLoader; +import org.treblereel.gwt.three4g.loaders.Loader; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; import org.treblereel.gwt.three4g.materials.Material; @@ -17,7 +17,7 @@ */ @Three4gElement(paths = {"js/loaders/MTLLoader.js"}) @JsType(isNative = true, namespace = "THREE") -public class MTLLoader extends AbstractLoader { +public class MTLLoader extends Loader { /** The loadingManager the loader is using. Default is DefaultLoadingManager. */ public LoadingManager manager; diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/TDSLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/TDSLoader.java index 80ca717c..d1717daf 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/TDSLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/TDSLoader.java @@ -5,7 +5,7 @@ import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.Three4gElement; import org.treblereel.gwt.three4g.core.Object3D; -import org.treblereel.gwt.three4g.loaders.AbstractLoader; +import org.treblereel.gwt.three4g.loaders.Loader; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; import org.treblereel.gwt.three4g.objects.Group; @@ -15,7 +15,7 @@ */ @Three4gElement(paths = "js/loaders/TDSLoader.js") @JsType(isNative = true, namespace = "THREE") -public class TDSLoader extends AbstractLoader { +public class TDSLoader extends Loader { public TDSLoader() { diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/VRMLLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/VRMLLoader.java index eda23a54..e2c8ff42 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/VRMLLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/VRMLLoader.java @@ -2,7 +2,7 @@ import jsinterop.annotations.JsType; import org.treblereel.gwt.three4g.Three4gElement; -import org.treblereel.gwt.three4g.loaders.AbstractLoader; +import org.treblereel.gwt.three4g.loaders.Loader; import org.treblereel.gwt.three4g.loaders.managers.LoadingManager; import org.treblereel.gwt.three4g.scenes.Scene; @@ -13,7 +13,7 @@ */ @Three4gElement(paths = {"js/libs/chevrotain.min.js", "js/loaders/VRMLLoader.js"}) @JsType(isNative = true, namespace = "THREE") -public class VRMLLoader extends AbstractLoader { +public class VRMLLoader extends Loader { public VRMLLoader() { diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/DragControls.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/DragControls.js index 9067e0ed..6ea844aa 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/DragControls.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/DragControls.js @@ -1,4 +1,4 @@ -/* +/** * @author zz85 / https://github.com/zz85 * @author mrdoob / http://mrdoob.com * Running this will allow you to drag three.js objects around the screen. diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/OrbitControls.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/OrbitControls.js index f23982ba..82792fb7 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/OrbitControls.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/OrbitControls.js @@ -460,32 +460,24 @@ THREE.OrbitControls = function ( object, domElement ) { function handleMouseDownRotate( event ) { - //console.log( 'handleMouseDownRotate' ); - rotateStart.set( event.clientX, event.clientY ); } function handleMouseDownDolly( event ) { - //console.log( 'handleMouseDownDolly' ); - dollyStart.set( event.clientX, event.clientY ); } function handleMouseDownPan( event ) { - //console.log( 'handleMouseDownPan' ); - panStart.set( event.clientX, event.clientY ); } function handleMouseMoveRotate( event ) { - //console.log( 'handleMouseMoveRotate' ); - rotateEnd.set( event.clientX, event.clientY ); rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); @@ -504,8 +496,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleMouseMoveDolly( event ) { - //console.log( 'handleMouseMoveDolly' ); - dollyEnd.set( event.clientX, event.clientY ); dollyDelta.subVectors( dollyEnd, dollyStart ); @@ -528,8 +518,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleMouseMovePan( event ) { - //console.log( 'handleMouseMovePan' ); - panEnd.set( event.clientX, event.clientY ); panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); @@ -544,14 +532,12 @@ THREE.OrbitControls = function ( object, domElement ) { function handleMouseUp( /*event*/ ) { - // console.log( 'handleMouseUp' ); + // no-op } function handleMouseWheel( event ) { - // console.log( 'handleMouseWheel' ); - if ( event.deltaY < 0 ) { dollyOut( getZoomScale() ); @@ -568,8 +554,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleKeyDown( event ) { - // console.log( 'handleKeyDown' ); - var needsUpdate = false; switch ( event.keyCode ) { @@ -610,8 +594,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchStartRotate( event ) { - //console.log( 'handleTouchStartRotate' ); - if ( event.touches.length == 1 ) { rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); @@ -629,8 +611,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchStartPan( event ) { - //console.log( 'handleTouchStartPan' ); - if ( event.touches.length == 1 ) { panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); @@ -648,8 +628,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchStartDolly( event ) { - //console.log( 'handleTouchStartDolly' ); - var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; @@ -661,8 +639,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchStartDollyPan( event ) { - //console.log( 'handleTouchStartDollyPan' ); - if ( scope.enableZoom ) handleTouchStartDolly( event ); if ( scope.enablePan ) handleTouchStartPan( event ); @@ -671,8 +647,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchStartDollyRotate( event ) { - //console.log( 'handleTouchStartDollyRotate' ); - if ( scope.enableZoom ) handleTouchStartDolly( event ); if ( scope.enableRotate ) handleTouchStartRotate( event ); @@ -681,8 +655,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchMoveRotate( event ) { - //console.log( 'handleTouchMoveRotate' ); - if ( event.touches.length == 1 ) { rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); @@ -710,8 +682,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchMovePan( event ) { - //console.log( 'handleTouchMoveRotate' ); - if ( event.touches.length == 1 ) { panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); @@ -735,8 +705,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchMoveDolly( event ) { - //console.log( 'handleTouchMoveRotate' ); - var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; @@ -754,8 +722,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchMoveDollyPan( event ) { - //console.log( 'handleTouchMoveDollyPan' ); - if ( scope.enableZoom ) handleTouchMoveDolly( event ); if ( scope.enablePan ) handleTouchMovePan( event ); @@ -764,8 +730,6 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchMoveDollyRotate( event ) { - //console.log( 'handleTouchMoveDollyPan' ); - if ( scope.enableZoom ) handleTouchMoveDolly( event ); if ( scope.enableRotate ) handleTouchMoveRotate( event ); @@ -774,7 +738,7 @@ THREE.OrbitControls = function ( object, domElement ) { function handleTouchEnd( /*event*/ ) { - //console.log( 'handleTouchEnd' ); + // no-op } @@ -1181,130 +1145,6 @@ THREE.OrbitControls = function ( object, domElement ) { THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; -Object.defineProperties( THREE.OrbitControls.prototype, { - - center: { - - get: function () { - - console.warn( 'THREE.OrbitControls: .center has been renamed to .target' ); - return this.target; - - } - - }, - - // backward compatibility - - noZoom: { - - get: function () { - - console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); - return ! this.enableZoom; - - }, - - set: function ( value ) { - - console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); - this.enableZoom = ! value; - - } - - }, - - noRotate: { - - get: function () { - - console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); - return ! this.enableRotate; - - }, - - set: function ( value ) { - - console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); - this.enableRotate = ! value; - - } - - }, - - noPan: { - - get: function () { - - console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); - return ! this.enablePan; - - }, - - set: function ( value ) { - - console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); - this.enablePan = ! value; - - } - - }, - - noKeys: { - - get: function () { - - console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); - return ! this.enableKeys; - - }, - - set: function ( value ) { - - console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); - this.enableKeys = ! value; - - } - - }, - - staticMoving: { - - get: function () { - - console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); - return ! this.enableDamping; - - }, - - set: function ( value ) { - - console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); - this.enableDamping = ! value; - - } - - }, - - dynamicDampingFactor: { - - get: function () { - - console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); - return this.dampingFactor; - - }, - - set: function ( value ) { - - console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); - this.dampingFactor = value; - - } - - } - -} ); // This set of controls performs orbiting, dollying (zooming), and panning. // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/PointerLockControls.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/PointerLockControls.js index b048e291..32bed902 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/PointerLockControls.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/controls/PointerLockControls.js @@ -5,9 +5,21 @@ THREE.PointerLockControls = function ( camera, domElement ) { - this.domElement = domElement || document.body; + if ( domElement === undefined ) { + + console.warn( 'THREE.PointerLockControls: The second parameter "domElement" is now mandatory.' ); + domElement = document.body; + + } + + this.domElement = domElement; this.isLocked = false; + // Set to constrain the pitch of the camera + // Range is 0 to Math.PI radians + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + // // internals // @@ -22,6 +34,8 @@ THREE.PointerLockControls = function ( camera, domElement ) { var PI_2 = Math.PI / 2; + var vec = new THREE.Vector3(); + function onMouseMove( event ) { if ( scope.isLocked === false ) return; @@ -34,7 +48,7 @@ THREE.PointerLockControls = function ( camera, domElement ) { euler.y -= movementX * 0.002; euler.x -= movementY * 0.002; - euler.x = Math.max( - PI_2, Math.min( PI_2, euler.x ) ); + euler.x = Math.max( PI_2 - scope.maxPolarAngle, Math.min( PI_2 - scope.minPolarAngle, euler.x ) ); camera.quaternion.setFromEuler( euler ); @@ -44,7 +58,7 @@ THREE.PointerLockControls = function ( camera, domElement ) { function onPointerlockChange() { - if ( document.pointerLockElement === scope.domElement ) { + if ( scope.domElement.ownerDocument.pointerLockElement === scope.domElement ) { scope.dispatchEvent( lockEvent ); @@ -68,17 +82,17 @@ THREE.PointerLockControls = function ( camera, domElement ) { this.connect = function () { - document.addEventListener( 'mousemove', onMouseMove, false ); - document.addEventListener( 'pointerlockchange', onPointerlockChange, false ); - document.addEventListener( 'pointerlockerror', onPointerlockError, false ); + scope.domElement.ownerDocument.addEventListener( 'mousemove', onMouseMove, false ); + scope.domElement.ownerDocument.addEventListener( 'pointerlockchange', onPointerlockChange, false ); + scope.domElement.ownerDocument.addEventListener( 'pointerlockerror', onPointerlockError, false ); }; this.disconnect = function () { - document.removeEventListener( 'mousemove', onMouseMove, false ); - document.removeEventListener( 'pointerlockchange', onPointerlockChange, false ); - document.removeEventListener( 'pointerlockerror', onPointerlockError, false ); + scope.domElement.ownerDocument.removeEventListener( 'mousemove', onMouseMove, false ); + scope.domElement.ownerDocument.removeEventListener( 'pointerlockchange', onPointerlockChange, false ); + scope.domElement.ownerDocument.removeEventListener( 'pointerlockerror', onPointerlockError, false ); }; @@ -106,6 +120,27 @@ THREE.PointerLockControls = function ( camera, domElement ) { }(); + this.moveForward = function ( distance ) { + + // move forward parallel to the xz-plane + // assumes camera.up is y-up + + vec.setFromMatrixColumn( camera.matrix, 0 ); + + vec.crossVectors( camera.up, vec ); + + camera.position.addScaledVector( vec, distance ); + + }; + + this.moveRight = function ( distance ) { + + vec.setFromMatrixColumn( camera.matrix, 0 ); + + camera.position.addScaledVector( vec, distance ); + + }; + this.lock = function () { this.domElement.requestPointerLock(); @@ -114,7 +149,7 @@ THREE.PointerLockControls = function ( camera, domElement ) { this.unlock = function () { - document.exitPointerLock(); + scope.domElement.ownerDocument.exitPointerLock(); }; @@ -123,4 +158,4 @@ THREE.PointerLockControls = function ( camera, domElement ) { }; THREE.PointerLockControls.prototype = Object.create( THREE.EventDispatcher.prototype ); -THREE.PointerLockControls.prototype.constructor = THREE.PointerLockControls; +THREE.PointerLockControls.prototype.constructor = THREE.PointerLockControls; \ No newline at end of file diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/effects/OutlineEffect.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/effects/OutlineEffect.js index fe06cd93..bbffa58e 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/effects/OutlineEffect.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/effects/OutlineEffect.js @@ -125,7 +125,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { var vertexShaderChunk2 = [ - "#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( PHYSICAL )", + "#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( STANDARD )", " #ifndef USE_ENVMAP", " vec3 objectNormal = normalize( normal );", " #endif", diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/exporters/GLTFExporter.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/exporters/GLTFExporter.js index 49af98dc..1f85c245 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/exporters/GLTFExporter.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/exporters/GLTFExporter.js @@ -867,6 +867,12 @@ THREE.GLTFExporter.prototype = { }; + if ( map.name ) { + + gltfTexture.name = map.name; + + } + outputJSON.textures.push( gltfTexture ); var index = outputJSON.textures.length - 1; @@ -895,7 +901,7 @@ THREE.GLTFExporter.prototype = { } - if ( material.isShaderMaterial ) { + if ( material.isShaderMaterial && !material.isGLTFSpecularGlossinessMaterial ) { console.warn( 'GLTFExporter: THREE.ShaderMaterial not supported.' ); return null; @@ -915,6 +921,12 @@ THREE.GLTFExporter.prototype = { extensionsUsed[ 'KHR_materials_unlit' ] = true; + } else if ( material.isGLTFSpecularGlossinessMaterial ) { + + gltfMaterial.extensions = { KHR_materials_pbrSpecularGlossiness: {} }; + + extensionsUsed[ 'KHR_materials_pbrSpecularGlossiness' ] = true; + } else if ( ! material.isMeshStandardMaterial ) { console.warn( 'GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.' ); @@ -947,6 +959,23 @@ THREE.GLTFExporter.prototype = { } + // pbrSpecularGlossiness diffuse, specular and glossiness factor + if ( material.isGLTFSpecularGlossinessMaterial ) { + + if ( gltfMaterial.pbrMetallicRoughness.baseColorFactor ) { + + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.diffuseFactor = gltfMaterial.pbrMetallicRoughness.baseColorFactor; + + } + + var specularFactor = [ 1, 1, 1 ]; + material.specular.toArray( specularFactor, 0 ); + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.specularFactor = specularFactor; + + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.glossinessFactor = material.glossiness; + + } + // pbrMetallicRoughness.metallicRoughnessTexture if ( material.metalnessMap || material.roughnessMap ) { @@ -964,12 +993,28 @@ THREE.GLTFExporter.prototype = { } - // pbrMetallicRoughness.baseColorTexture + // pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture if ( material.map ) { var baseColorMapDef = { index: processTexture( material.map ) }; applyTextureTransform( baseColorMapDef, material.map ); + + if ( material.isGLTFSpecularGlossinessMaterial ) { + + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.diffuseTexture = baseColorMapDef; + + } + gltfMaterial.pbrMetallicRoughness.baseColorTexture = baseColorMapDef; + + } + + // pbrSpecularGlossiness specular map + if ( material.isGLTFSpecularGlossinessMaterial && material.specularMap ) { + + var specularMapDef = { index: processTexture( material.specularMap ) }; + applyTextureTransform( specularMapDef, material.specularMap ); + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.specularGlossinessTexture = specularMapDef; } @@ -1004,7 +1049,7 @@ THREE.GLTFExporter.prototype = { var normalMapDef = { index: processTexture( material.normalMap ) }; - if ( material.normalScale.x !== - 1 ) { + if ( material.normalScale && material.normalScale.x !== - 1 ) { if ( material.normalScale.x !== material.normalScale.y ) { diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/AMFLoader.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/AMFLoader.js index 55ef7cd3..5ff54107 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/AMFLoader.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/AMFLoader.js @@ -1,4 +1,4 @@ -/* +/** * @author tamarintech / https://tamarintech.com * * Description: Early release of an AMF Loader following the pattern of the diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/DRACOLoader.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/DRACOLoader.js index 3b6ad570..0b0392d9 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/DRACOLoader.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/DRACOLoader.js @@ -1,723 +1,626 @@ -/** Copyright 2016 The Draco Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /** - * @param {THREE.LoadingManager} manager + * @author Don McCurdy / https://www.donmccurdy.com */ + THREE.DRACOLoader = function ( manager ) { - this.timeLoaded = 0; this.manager = manager || THREE.DefaultLoadingManager; - this.materials = null; - this.verbosity = 0; - this.attributeOptions = {}; - this.drawMode = THREE.TrianglesDrawMode; - // Native Draco attribute type to Three.JS attribute type. - this.nativeAttributeMap = { - position: "POSITION", - normal: "NORMAL", - color: "COLOR", - uv: "TEX_COORD" + + this.path = ''; + this.crossOrigin = 'anonymous'; + + this.decoderPath = ''; + this.decoderConfig = {}; + this.decoderBinary = null; + this.decoderPending = null; + + this.workerLimit = 4; + this.workerPool = []; + this.workerNextTaskID = 1; + this.workerSourceURL = ''; + + this.defaultAttributeIDs = { + position: 'POSITION', + normal: 'NORMAL', + color: 'COLOR', + uv: 'TEX_COORD' + }; + this.defaultAttributeTypes = { + position: 'Float32Array', + normal: 'Float32Array', + color: 'Float32Array', + uv: 'Float32Array' }; }; THREE.DRACOLoader.prototype = { - constructor: THREE.DRACOLoader, - load: function ( url, onLoad, onProgress, onError ) { + constructor: THREE.DRACOLoader, - var scope = this; - var loader = new THREE.FileLoader( scope.manager ); - loader.setPath( this.path ); - loader.setResponseType( "arraybuffer" ); - loader.load( - url, - function ( blob ) { + setPath: function ( path ) { - scope.decodeDracoFile( blob, onLoad ); + this.path = path; - }, - onProgress, - onError - ); + return this; }, - setPath: function ( value ) { + setCrossOrigin: function ( crossOrigin ) { + + this.crossOrigin = crossOrigin; - this.path = value; return this; }, - setVerbosity: function ( level ) { + setDecoderPath: function ( path ) { + + this.decoderPath = path; - this.verbosity = level; return this; }, - /** - * Sets desired mode for generated geometry indices. - * Can be either: - * THREE.TrianglesDrawMode - * THREE.TriangleStripDrawMode - */ - setDrawMode: function ( drawMode ) { + setDecoderConfig: function ( config ) { + + this.decoderConfig = config; - this.drawMode = drawMode; return this; }, - /** - * Skips dequantization for a specific attribute. - * |attributeName| is the THREE.js name of the given attribute type. - * The only currently supported |attributeName| is 'position', more may be - * added in future. - */ - setSkipDequantization: function ( attributeName, skip ) { - - var skipDequantization = true; - if ( typeof skip !== "undefined" ) skipDequantization = skip; - this.getAttributeOptions( - attributeName - ).skipDequantization = skipDequantization; + setWorkerLimit: function ( workerLimit ) { + + this.workerLimit = workerLimit; + return this; }, - /** - * Decompresses a Draco buffer. Names of attributes (for ID and type maps) - * must be one of the supported three.js types, including: position, color, - * normal, uv, uv2, skinIndex, skinWeight. - * - * @param {ArrayBuffer} rawBuffer - * @param {Function} callback - * @param {Object|undefined} attributeUniqueIdMap Provides a pre-defined ID - * for each attribute in the geometry to be decoded. If given, - * `attributeTypeMap` is required and `nativeAttributeMap` will be - * ignored. - * @param {Object|undefined} attributeTypeMap Provides a predefined data - * type (as a typed array constructor) for each attribute in the - * geometry to be decoded. - */ - decodeDracoFile: function ( - rawBuffer, - callback, - attributeUniqueIdMap, - attributeTypeMap - ) { - - var scope = this; - THREE.DRACOLoader.getDecoderModule().then( function ( module ) { - - scope.decodeDracoFileInternal( - rawBuffer, - module.decoder, - callback, - attributeUniqueIdMap, - attributeTypeMap - ); + /** @deprecated */ + setVerbosity: function () { - } ); + console.warn( 'THREE.DRACOLoader: The .setVerbosity() method has been removed.' ); }, - decodeDracoFileInternal: function ( - rawBuffer, - dracoDecoder, - callback, - attributeUniqueIdMap, - attributeTypeMap - ) { + /** @deprecated */ + setDrawMode: function () { - /* - * Here is how to use Draco Javascript decoder and get the geometry. - */ - var buffer = new dracoDecoder.DecoderBuffer(); - buffer.Init( new Int8Array( rawBuffer ), rawBuffer.byteLength ); - var decoder = new dracoDecoder.Decoder(); + console.warn( 'THREE.DRACOLoader: The .setDrawMode() method has been removed.' ); - /* - * Determine what type is this file: mesh or point cloud. - */ - var geometryType = decoder.GetEncodedGeometryType( buffer ); - if ( geometryType == dracoDecoder.TRIANGULAR_MESH ) { - - if ( this.verbosity > 0 ) { + }, - console.log( "Loaded a mesh." ); + /** @deprecated */ + setSkipDequantization: function () { - } + console.warn( 'THREE.DRACOLoader: The .setSkipDequantization() method has been removed.' ); - } else if ( geometryType == dracoDecoder.POINT_CLOUD ) { + }, - if ( this.verbosity > 0 ) { + load: function ( url, onLoad, onProgress, onError ) { - console.log( "Loaded a point cloud." ); + var loader = new THREE.FileLoader( this.manager ); - } + loader.setPath( this.path ); + loader.setResponseType( 'arraybuffer' ); - } else { + if ( this.crossOrigin === 'use-credentials' ) { - var errorMsg = "THREE.DRACOLoader: Unknown geometry type."; - console.error( errorMsg ); - throw new Error( errorMsg ); + loader.setWithCredentials( true ); } - callback( - this.convertDracoGeometryTo3JS( - dracoDecoder, - decoder, - geometryType, - buffer, - attributeUniqueIdMap, - attributeTypeMap - ) - ); + + loader.load( url, ( buffer ) => { + + var taskConfig = { + attributeIDs: this.defaultAttributeIDs, + attributeTypes: this.defaultAttributeTypes + }; + + this.decodeGeometry( buffer, taskConfig ) + .then( onLoad ) + .catch( onError ); + + }, onProgress, onError ); + + }, + + /** @deprecated Kept for backward-compatibility with previous DRACOLoader versions. */ + decodeDracoFile: function ( buffer, callback, attributeIDs, attributeTypes ) { + + var taskConfig = { + attributeIDs: attributeIDs || this.defaultAttributeIDs, + attributeTypes: attributeTypes || this.defaultAttributeTypes + }; + + this.decodeGeometry( buffer, taskConfig ).then( callback ); }, - addAttributeToGeometry: function ( - dracoDecoder, - decoder, - dracoGeometry, - attributeName, - attributeType, - attribute, - geometry, - geometryBuffer - ) { + decodeGeometry: function ( buffer, taskConfig ) { - if ( attribute.ptr === 0 ) { + var worker; + var taskID = this.workerNextTaskID ++; + var taskCost = buffer.byteLength; - var errorMsg = "THREE.DRACOLoader: No attribute " + attributeName; - console.error( errorMsg ); - throw new Error( errorMsg ); + // TODO: For backward-compatibility, support 'attributeTypes' objects containing + // references (rather than names) to typed array constructors. These must be + // serialized before sending them to the worker. + for ( var attribute in taskConfig.attributeTypes ) { + + var type = taskConfig.attributeTypes[ attribute ]; + + if ( type.BYTES_PER_ELEMENT !== undefined ) { + + taskConfig.attributeTypes[ attribute ] = type.name; + + } } - var numComponents = attribute.num_components(); - var numPoints = dracoGeometry.num_points(); - var numValues = numPoints * numComponents; - var attributeData; - var TypedBufferAttribute; + // Obtain a worker and assign a task, and construct a geometry instance + // when the task completes. + var geometryPending = this._getWorker( taskID, taskCost ) + .then( ( _worker ) => { - switch ( attributeType ) { + worker = _worker; - case Float32Array: - attributeData = new dracoDecoder.DracoFloat32Array(); - decoder.GetAttributeFloatForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Float32Array( numValues ); - TypedBufferAttribute = THREE.Float32BufferAttribute; - break; + return new Promise( ( resolve, reject ) => { - case Int8Array: - attributeData = new dracoDecoder.DracoInt8Array(); - decoder.GetAttributeInt8ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Int8Array( numValues ); - TypedBufferAttribute = THREE.Int8BufferAttribute; - break; + worker._callbacks[ taskID ] = { resolve, reject }; - case Int16Array: - attributeData = new dracoDecoder.DracoInt16Array(); - decoder.GetAttributeInt16ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Int16Array( numValues ); - TypedBufferAttribute = THREE.Int16BufferAttribute; - break; + worker.postMessage( { type: 'decode', id: taskID, taskConfig, buffer }, [ buffer ] ); - case Int32Array: - attributeData = new dracoDecoder.DracoInt32Array(); - decoder.GetAttributeInt32ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Int32Array( numValues ); - TypedBufferAttribute = THREE.Int32BufferAttribute; - break; + // this.debug(); - case Uint8Array: - attributeData = new dracoDecoder.DracoUInt8Array(); - decoder.GetAttributeUInt8ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Uint8Array( numValues ); - TypedBufferAttribute = THREE.Uint8BufferAttribute; - break; + } ); - case Uint16Array: - attributeData = new dracoDecoder.DracoUInt16Array(); - decoder.GetAttributeUInt16ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Uint16Array( numValues ); - TypedBufferAttribute = THREE.Uint16BufferAttribute; - break; + } ) + .then( ( message ) => this._createGeometry( message.geometry ) ); - case Uint32Array: - attributeData = new dracoDecoder.DracoUInt32Array(); - decoder.GetAttributeUInt32ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Uint32Array( numValues ); - TypedBufferAttribute = THREE.Uint32BufferAttribute; - break; + // Remove task from the task list. + geometryPending + .finally( () => { - default: - var errorMsg = "THREE.DRACOLoader: Unexpected attribute type."; - console.error( errorMsg ); - throw new Error( errorMsg ); + if ( worker && taskID ) { - } + this._releaseTask( worker, taskID ); - // Copy data from decoder. - for ( var i = 0; i < numValues; i ++ ) { + // this.debug(); - geometryBuffer[ attributeName ][ i ] = attributeData.GetValue( i ); + } - } - // Add attribute to THREEJS geometry for rendering. - geometry.addAttribute( - attributeName, - new TypedBufferAttribute( geometryBuffer[ attributeName ], numComponents ) - ); - dracoDecoder.destroy( attributeData ); + } ); + + return geometryPending; }, - convertDracoGeometryTo3JS: function ( - dracoDecoder, - decoder, - geometryType, - buffer, - attributeUniqueIdMap, - attributeTypeMap - ) { + _createGeometry: function ( geometryData ) { + + var geometry = new THREE.BufferGeometry(); - // TODO: Should not assume native Draco attribute IDs apply. - if ( this.getAttributeOptions( "position" ).skipDequantization === true ) { + if ( geometryData.index ) { - decoder.SkipAttributeTransform( dracoDecoder.POSITION ); + geometry.setIndex( new THREE.BufferAttribute( geometryData.index.array, 1 ) ); } - var dracoGeometry; - var decodingStatus; - var start_time = performance.now(); - if ( geometryType === dracoDecoder.TRIANGULAR_MESH ) { - dracoGeometry = new dracoDecoder.Mesh(); - decodingStatus = decoder.DecodeBufferToMesh( buffer, dracoGeometry ); + for ( var i = 0; i < geometryData.attributes.length; i++ ) { - } else { + var attribute = geometryData.attributes[ i ]; + var name = attribute.name; + var array = attribute.array; + var itemSize = attribute.itemSize; - dracoGeometry = new dracoDecoder.PointCloud(); - decodingStatus = decoder.DecodeBufferToPointCloud( buffer, dracoGeometry ); + geometry.addAttribute( name, new THREE.BufferAttribute( array, itemSize ) ); } - if ( ! decodingStatus.ok() || dracoGeometry.ptr == 0 ) { - var errorMsg = "THREE.DRACOLoader: Decoding failed: "; - errorMsg += decodingStatus.error_msg(); - console.error( errorMsg ); - dracoDecoder.destroy( decoder ); - dracoDecoder.destroy( dracoGeometry ); - throw new Error( errorMsg ); + return geometry; - } + }, - var decode_end = performance.now(); - dracoDecoder.destroy( buffer ); - /* - * Example on how to retrieve mesh and attributes. - */ - var numFaces; - if ( geometryType == dracoDecoder.TRIANGULAR_MESH ) { + _loadLibrary: function ( url, responseType ) { - numFaces = dracoGeometry.num_faces(); - if ( this.verbosity > 0 ) { + var loader = new THREE.FileLoader( this.manager ); + loader.setPath( this.decoderPath ); + loader.setResponseType( responseType ); - console.log( "Number of faces loaded: " + numFaces.toString() ); + return new Promise( ( resolve, reject ) => { - } + loader.load( url, resolve, undefined, reject ); + + } ); + + }, + + _initDecoder: function () { + + if ( this.decoderPending ) return this.decoderPending; + + var useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js'; + var librariesPending = []; + + if ( useJS ) { + + librariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) ); } else { - numFaces = 0; + librariesPending.push( this._loadLibrary( 'draco_wasm_wrapper.js', 'text' ) ); + librariesPending.push( this._loadLibrary( 'draco_decoder.wasm', 'arraybuffer' ) ); } - var numPoints = dracoGeometry.num_points(); - var numAttributes = dracoGeometry.num_attributes(); - if ( this.verbosity > 0 ) { + this.decoderPending = Promise.all( librariesPending ) + .then( ( libraries ) => { - console.log( "Number of points loaded: " + numPoints.toString() ); - console.log( "Number of attributes loaded: " + numAttributes.toString() ); + var jsContent = libraries[ 0 ]; - } + if ( ! useJS ) { - // Verify if there is position attribute. - // TODO: Should not assume native Draco attribute IDs apply. - var posAttId = decoder.GetAttributeId( dracoGeometry, dracoDecoder.POSITION ); - if ( posAttId == - 1 ) { + this.decoderConfig.wasmBinary = libraries[ 1 ]; - var errorMsg = "THREE.DRACOLoader: No position attribute found."; - console.error( errorMsg ); - dracoDecoder.destroy( decoder ); - dracoDecoder.destroy( dracoGeometry ); - throw new Error( errorMsg ); + } - } - var posAttribute = decoder.GetAttribute( dracoGeometry, posAttId ); + var fn = THREE.DRACOLoader.DRACOWorker.toString(); - // Structure for converting to THREEJS geometry later. - var geometryBuffer = {}; - // Import data to Three JS geometry. - var geometry = new THREE.BufferGeometry(); + var body = [ + '/* draco decoder */', + jsContent, + '', + '/* worker */', + fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) ) + ].join( '\n' ); - // Do not use both the native attribute map and a provided (e.g. glTF) map. - if ( attributeUniqueIdMap ) { - - // Add attributes of user specified unique id. E.g. GLTF models. - for ( var attributeName in attributeUniqueIdMap ) { - - var attributeType = attributeTypeMap[ attributeName ]; - var attributeId = attributeUniqueIdMap[ attributeName ]; - var attribute = decoder.GetAttributeByUniqueId( - dracoGeometry, - attributeId - ); - this.addAttributeToGeometry( - dracoDecoder, - decoder, - dracoGeometry, - attributeName, - attributeType, - attribute, - geometry, - geometryBuffer - ); + this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) ); - } + } ); - } else { + return this.decoderPending; - // Add native Draco attribute type to geometry. - for ( var attributeName in this.nativeAttributeMap ) { + }, - var attId = decoder.GetAttributeId( - dracoGeometry, - dracoDecoder[ this.nativeAttributeMap[ attributeName ] ] - ); - if ( attId !== - 1 ) { + _getWorker: function ( taskID, taskCost ) { - if ( this.verbosity > 0 ) { + return this._initDecoder().then( () => { - console.log( "Loaded " + attributeName + " attribute." ); + if ( this.workerPool.length < this.workerLimit ) { - } - var attribute = decoder.GetAttribute( dracoGeometry, attId ); - this.addAttributeToGeometry( - dracoDecoder, - decoder, - dracoGeometry, - attributeName, - Float32Array, - attribute, - geometry, - geometryBuffer - ); + var worker = new Worker( this.workerSourceURL ); - } + worker._callbacks = {}; + worker._taskCosts = {}; + worker._taskLoad = 0; - } + worker.postMessage( { type: 'init', decoderConfig: this.decoderConfig } ); - } + worker.onmessage = function ( e ) { - // For mesh, we need to generate the faces. - if ( geometryType == dracoDecoder.TRIANGULAR_MESH ) { + var message = e.data; - if ( this.drawMode === THREE.TriangleStripDrawMode ) { + switch ( message.type ) { - var stripsArray = new dracoDecoder.DracoInt32Array(); - decoder.GetTriangleStripsFromMesh( - dracoGeometry, - stripsArray - ); - geometryBuffer.indices = new Uint32Array( stripsArray.size() ); - for ( var i = 0; i < stripsArray.size(); ++ i ) { + case 'decode': + worker._callbacks[ message.id ].resolve( message ); + break; - geometryBuffer.indices[ i ] = stripsArray.GetValue( i ); + case 'error': + worker._callbacks[ message.id ].reject( message ); + break; - } - dracoDecoder.destroy( stripsArray ); + default: + console.error( 'THREE.DRACOLoader: Unexpected message, "' + message.type + '"' ); + + } + + }; + + this.workerPool.push( worker ); } else { - var numIndices = numFaces * 3; - geometryBuffer.indices = new Uint32Array( numIndices ); - var ia = new dracoDecoder.DracoInt32Array(); - for ( var i = 0; i < numFaces; ++ i ) { + this.workerPool.sort( function ( a, b ) { - decoder.GetFaceFromMesh( dracoGeometry, i, ia ); - var index = i * 3; - geometryBuffer.indices[ index ] = ia.GetValue( 0 ); - geometryBuffer.indices[ index + 1 ] = ia.GetValue( 1 ); - geometryBuffer.indices[ index + 2 ] = ia.GetValue( 2 ); + return a._taskLoad > b._taskLoad ? - 1 : 1; - } - dracoDecoder.destroy( ia ); + } ); } - } + var worker = this.workerPool[ this.workerPool.length - 1 ]; + worker._taskCosts[ taskID ] = taskCost; + worker._taskLoad += taskCost; + return worker; + + } ); + + }, + + _releaseTask: function ( worker, taskID ) { + + worker._taskLoad -= worker._taskCosts[ taskID ]; + delete worker._callbacks[ taskID ]; + delete worker._taskCosts[ taskID ]; + + }, + + debug: function () { - geometry.drawMode = this.drawMode; - if ( geometryType == dracoDecoder.TRIANGULAR_MESH ) { + console.log( 'Task load: ', this.workerPool.map( ( worker ) => worker._taskLoad ) ); - geometry.setIndex( - new ( geometryBuffer.indices.length > 65535 - ? THREE.Uint32BufferAttribute - : THREE.Uint16BufferAttribute )( geometryBuffer.indices, 1 ) - ); + }, + + dispose: function () { + + for ( var i = 0; i < this.workerPool.length; ++ i ) { + + this.workerPool[ i ].terminate(); } - // TODO: Should not assume native Draco attribute IDs apply. - // TODO: Can other attribute types be quantized? - var posTransform = new dracoDecoder.AttributeQuantizationTransform(); - if ( posTransform.InitFromAttribute( posAttribute ) ) { - - // Quantized attribute. Store the quantization parameters into the - // THREE.js attribute. - geometry.attributes[ "position" ].isQuantized = true; - geometry.attributes[ "position" ].maxRange = posTransform.range(); - geometry.attributes[ - "position" - ].numQuantizationBits = posTransform.quantization_bits(); - geometry.attributes[ "position" ].minValues = new Float32Array( 3 ); - for ( var i = 0; i < 3; ++ i ) { - - geometry.attributes[ "position" ].minValues[ i ] = posTransform.min_value( - i - ); + this.workerPool.length = 0; - } + return this; + + } +}; + +/* WEB WORKER */ + +THREE.DRACOLoader.DRACOWorker = function () { + + var decoderConfig; + var decoderPending; + + onmessage = function ( e ) { + + var message = e.data; + + switch ( message.type ) { + + case 'init': + decoderConfig = message.decoderConfig; + decoderPending = new Promise( function ( resolve, reject ) { + + decoderConfig.onModuleLoaded = function ( draco ) { + + // Module is Promise-like. Wrap before resolving to avoid loop. + resolve( { draco: draco } ); + + }; + + DracoDecoderModule( decoderConfig ); + + } ); + break; + + case 'decode': + var buffer = message.buffer; + var taskConfig = message.taskConfig; + decoderPending.then( ( module ) => { + + var draco = module.draco; + var decoder = new draco.Decoder(); + var decoderBuffer = new draco.DecoderBuffer(); + decoderBuffer.Init( new Int8Array( buffer ), buffer.byteLength ); + + try { + + var geometry = decodeGeometry( draco, decoder, decoderBuffer, taskConfig ); + + var buffers = geometry.attributes.map( ( attr ) => attr.array.buffer ); + + if ( geometry.index ) buffers.push( geometry.index.array.buffer ); + + self.postMessage( { type: 'decode', id: message.id, geometry }, buffers ); + + } catch ( error ) { + + console.error( error ); + + self.postMessage( { type: 'error', id: message.id, error: error.message } ); + + } finally { + + draco.destroy( decoderBuffer ); + draco.destroy( decoder ); + + } + + } ); + break; } - dracoDecoder.destroy( posTransform ); - dracoDecoder.destroy( decoder ); - dracoDecoder.destroy( dracoGeometry ); - this.decode_time = decode_end - start_time; - this.import_time = performance.now() - decode_end; + }; + + function decodeGeometry( draco, decoder, decoderBuffer, taskConfig ) { + + var attributeIDs = taskConfig.attributeIDs; + var attributeTypes = taskConfig.attributeTypes; + + var dracoGeometry; + var decodingStatus; - if ( this.verbosity > 0 ) { + var geometryType = decoder.GetEncodedGeometryType( decoderBuffer ); - console.log( "Decode time: " + this.decode_time ); - console.log( "Import time: " + this.import_time ); + if ( geometryType === draco.TRIANGULAR_MESH ) { + + dracoGeometry = new draco.Mesh(); + decodingStatus = decoder.DecodeBufferToMesh( decoderBuffer, dracoGeometry ); + + } else if ( geometryType === draco.POINT_CLOUD ) { + + dracoGeometry = new draco.PointCloud(); + decodingStatus = decoder.DecodeBufferToPointCloud( decoderBuffer, dracoGeometry ); + + } else { + + throw new Error( 'THREE.DRACOLoader: Unexpected geometry type.' ); } - return geometry; - }, + if ( ! decodingStatus.ok() || dracoGeometry.ptr === 0 ) { - isVersionSupported: function ( version, callback ) { + throw new Error( 'THREE.DRACOLoader: Decoding failed: ' + decodingStatus.error_msg() ); - THREE.DRACOLoader.getDecoderModule().then( function ( module ) { + } - callback( module.decoder.isVersionSupported( version ) ); + var geometry = { index: null, attributes: [] }; - } ); + var numPoints = dracoGeometry.num_points(); + var numAttributes = dracoGeometry.num_attributes(); - }, + // Add attributes of user specified unique id. + for (var attributeName in attributeIDs) { - getAttributeOptions: function ( attributeName ) { + var attributeType = self[ attributeTypes[ attributeName ] ]; + var attributeId = attributeIDs[ attributeName ]; + var attribute = decoder.GetAttributeByUniqueId( dracoGeometry, attributeId ); - if ( typeof this.attributeOptions[ attributeName ] === "undefined" ) - this.attributeOptions[ attributeName ] = {}; - return this.attributeOptions[ attributeName ]; + geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) ); - } -}; + } -THREE.DRACOLoader.decoderPath = "./"; -THREE.DRACOLoader.decoderConfig = {}; -THREE.DRACOLoader.decoderModulePromise = null; + // Add index. + if ( geometryType === draco.TRIANGULAR_MESH ) { -/** - * Sets the base path for decoder source files. - * @param {string} path - */ -THREE.DRACOLoader.setDecoderPath = function ( path ) { + // Generate mesh faces. + var numFaces = dracoGeometry.num_faces(); + var numIndices = numFaces * 3; + var index = new Uint32Array( numIndices ); + var indexArray = new draco.DracoInt32Array(); - THREE.DRACOLoader.decoderPath = path; + for ( var i = 0; i < numFaces; ++ i ) { -}; + decoder.GetFaceFromMesh( dracoGeometry, i, indexArray ); -/** - * Sets decoder configuration and releases singleton decoder module. Module - * will be recreated with the next decoding call. - * @param {Object} config - */ -THREE.DRACOLoader.setDecoderConfig = function ( config ) { + for ( var j = 0; j < 3; ++ j ) { - var wasmBinary = THREE.DRACOLoader.decoderConfig.wasmBinary; - THREE.DRACOLoader.decoderConfig = config || {}; - THREE.DRACOLoader.releaseDecoderModule(); + index[ i * 3 + j ] = indexArray.GetValue( j ); - // Reuse WASM binary. - if ( wasmBinary ) THREE.DRACOLoader.decoderConfig.wasmBinary = wasmBinary; + } -}; + } -/** - * Releases the singleton DracoDecoderModule instance. Module will be recreated - * with the next decoding call. - */ -THREE.DRACOLoader.releaseDecoderModule = function () { + geometry.index = { array: index, itemSize: 1 }; - THREE.DRACOLoader.decoderModulePromise = null; + draco.destroy( indexArray ); -}; + } -/** - * Gets WebAssembly or asm.js singleton instance of DracoDecoderModule - * after testing for browser support. Returns Promise that resolves when - * module is available. - * @return {Promise<{decoder: DracoDecoderModule}>} - */ -THREE.DRACOLoader.getDecoderModule = function () { + draco.destroy( dracoGeometry ); - var scope = this; - var path = THREE.DRACOLoader.decoderPath; - var config = THREE.DRACOLoader.decoderConfig; - var promise = THREE.DRACOLoader.decoderModulePromise; + return geometry; - if ( promise ) return promise; + }; - // Load source files. - if ( typeof DracoDecoderModule !== "undefined" ) { + function decodeAttribute ( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) { - // Loaded externally. - promise = Promise.resolve(); + var numComponents = attribute.num_components(); + var numPoints = dracoGeometry.num_points(); + var numValues = numPoints * numComponents; + var dracoArray; - } else if ( typeof WebAssembly !== "object" || config.type === "js" ) { + var array; - // Load with asm.js. - promise = THREE.DRACOLoader._loadScript( path + "draco_decoder.js" ); + switch ( attributeType ) { - } else { + case Float32Array: + dracoArray = new draco.DracoFloat32Array(); + decoder.GetAttributeFloatForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Float32Array( numValues ); + break; - // Load with WebAssembly. - config.wasmBinaryFile = path + "draco_decoder.wasm"; - promise = THREE.DRACOLoader._loadScript( path + "draco_wasm_wrapper.js" ) - .then( function () { + case Int8Array: + dracoArray = new draco.DracoInt8Array(); + decoder.GetAttributeInt8ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Int8Array( numValues ); + break; - return THREE.DRACOLoader._loadArrayBuffer( config.wasmBinaryFile ); + case Int16Array: + dracoArray = new draco.DracoInt16Array(); + decoder.GetAttributeInt16ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Int16Array( numValues ); + break; - } ) - .then( function ( wasmBinary ) { + case Int32Array: + dracoArray = new draco.DracoInt32Array(); + decoder.GetAttributeInt32ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Int32Array( numValues ); + break; - config.wasmBinary = wasmBinary; + case Uint8Array: + dracoArray = new draco.DracoUInt8Array(); + decoder.GetAttributeUInt8ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Uint8Array( numValues ); + break; - } ); + case Uint16Array: + dracoArray = new draco.DracoUInt16Array(); + decoder.GetAttributeUInt16ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Uint16Array( numValues ); + break; - } + case Uint32Array: + dracoArray = new draco.DracoUInt32Array(); + decoder.GetAttributeUInt32ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Uint32Array( numValues ); + break; - // Wait for source files, then create and return a decoder. - promise = promise.then( function () { + default: + throw new Error( 'THREE.DRACOLoader: Unexpected attribute type.' ); - return new Promise( function ( resolve ) { + } - config.onModuleLoaded = function ( decoder ) { + for ( var i = 0; i < numValues; i++ ) { - scope.timeLoaded = performance.now(); - // Module is Promise-like. Wrap before resolving to avoid loop. - resolve( { decoder: decoder } ); + array[ i ] = dracoArray.GetValue( i ); - }; - DracoDecoderModule( config ); + } - } ); + draco.destroy( dracoArray ); - } ); + return { + name: attributeName, + array: array, + itemSize: numComponents + }; - THREE.DRACOLoader.decoderModulePromise = promise; - return promise; + }; }; -/** - * @param {string} src - * @return {Promise} - */ -THREE.DRACOLoader._loadScript = function ( src ) { +/** Deprecated static methods */ - var prevScript = document.getElementById( "decoder_script" ); - if ( prevScript !== null ) { +/** @deprecated */ +THREE.DRACOLoader.setDecoderPath = function () { - prevScript.parentNode.removeChild( prevScript ); + console.warn( 'THREE.DRACOLoader: The .setDecoderPath() method has been removed. Use instance methods.' ); - } - var head = document.getElementsByTagName( "head" )[ 0 ]; - var script = document.createElement( "script" ); - script.id = "decoder_script"; - script.type = "text/javascript"; - script.src = src; - return new Promise( function ( resolve ) { +}; - script.onload = resolve; - head.appendChild( script ); +/** @deprecated */ +THREE.DRACOLoader.setDecoderConfig = function () { - } ); + console.warn( 'THREE.DRACOLoader: The .setDecoderConfig() method has been removed. Use instance methods.' ); }; -/** - * @param {string} src - * @return {Promise} - */ -THREE.DRACOLoader._loadArrayBuffer = function ( src ) { +/** @deprecated */ +THREE.DRACOLoader.releaseDecoderModule = function () { - var loader = new THREE.FileLoader(); - loader.setResponseType( "arraybuffer" ); - return new Promise( function ( resolve, reject ) { + console.warn( 'THREE.DRACOLoader: The .releaseDecoderModule() method has been removed. Use instance methods.' ); - loader.load( src, resolve, undefined, reject ); +}; + +/** @deprecated */ +THREE.DRACOLoader.getDecoderModule = function () { - } ); + console.warn( 'THREE.DRACOLoader: The .getDecoderModule() method has been removed. Use instance methods.' ); }; diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/GLTFLoader.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/GLTFLoader.js index 8e2c3e91..c071cec5 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/GLTFLoader.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/GLTFLoader.js @@ -726,7 +726,7 @@ THREE.GLTFLoader = ( function () { materialParams.vertexShader = shader.vertexShader; materialParams.fragmentShader = fragmentShader; materialParams.uniforms = uniforms; - materialParams.defines = { 'STANDARD': '' }; + materialParams.defines = { 'STANDARD': '' } materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); materialParams.opacity = 1.0; @@ -2140,6 +2140,7 @@ THREE.GLTFLoader = ( function () { pointsMaterial.color.copy( material.color ); pointsMaterial.map = material.map; pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet + pointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px this.cache.add( cacheKey, pointsMaterial ); diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/TDSLoader.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/TDSLoader.js index 8f527d31..b0306c78 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/TDSLoader.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/TDSLoader.js @@ -1,4 +1,4 @@ -/* +/** * Autodesk 3DS three.js file loader, based on lib3ds. * * Loads geometry with uv and materials basic properties with texture support. diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/TGALoader.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/TGALoader.js index db833edb..b84c9594 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/TGALoader.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/TGALoader.js @@ -1,4 +1,4 @@ -/* +/** * @author Daosheng Mu / https://github.com/DaoshengMu/ * @author mrdoob / http://mrdoob.com/ * @author takahirox / https://github.com/takahirox/ diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/deprecated/LegacyJSONLoader.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/deprecated/LegacyJSONLoader.js index 0746af11..5fb0b94d 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/deprecated/LegacyJSONLoader.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/loaders/deprecated/LegacyJSONLoader.js @@ -85,6 +85,270 @@ THREE.LegacyJSONLoader = ( function () { parse: ( function () { + var _BlendingMode = { + NoBlending: THREE.NoBlending, + NormalBlending: THREE.NormalBlending, + AdditiveBlending: THREE.AdditiveBlending, + SubtractiveBlending: THREE.SubtractiveBlending, + MultiplyBlending: THREE.MultiplyBlending, + CustomBlending: THREE.CustomBlending + }; + + var _color = new THREE.Color(); + var _textureLoader = new THREE.TextureLoader(); + var _materialLoader = new THREE.MaterialLoader(); + + function initMaterials( materials, texturePath, crossOrigin ) { + + var array = []; + + for ( var i = 0; i < materials.length; ++ i ) { + + array[ i ] = createMaterial( materials[ i ], texturePath, crossOrigin ); + + } + + return array; + + } + + function createMaterial( m, texturePath, crossOrigin ) { + + // convert from old material format + + var textures = {}; + + // + + var json = { + uuid: THREE.Math.generateUUID(), + type: 'MeshLambertMaterial' + }; + + for ( var name in m ) { + + var value = m[ name ]; + + switch ( name ) { + + case 'DbgColor': + case 'DbgIndex': + case 'opticalDensity': + case 'illumination': + break; + case 'DbgName': + json.name = value; + break; + case 'blending': + json.blending = _BlendingMode[ value ]; + break; + case 'colorAmbient': + case 'mapAmbient': + console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' ); + break; + case 'colorDiffuse': + json.color = _color.fromArray( value ).getHex(); + break; + case 'colorSpecular': + json.specular = _color.fromArray( value ).getHex(); + break; + case 'colorEmissive': + json.emissive = _color.fromArray( value ).getHex(); + break; + case 'specularCoef': + json.shininess = value; + break; + case 'shading': + if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial'; + if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial'; + if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial'; + break; + case 'mapDiffuse': + json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapDiffuseRepeat': + case 'mapDiffuseOffset': + case 'mapDiffuseWrap': + case 'mapDiffuseAnisotropy': + break; + case 'mapEmissive': + json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapEmissiveRepeat': + case 'mapEmissiveOffset': + case 'mapEmissiveWrap': + case 'mapEmissiveAnisotropy': + break; + case 'mapLight': + json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapLightRepeat': + case 'mapLightOffset': + case 'mapLightWrap': + case 'mapLightAnisotropy': + break; + case 'mapAO': + json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapAORepeat': + case 'mapAOOffset': + case 'mapAOWrap': + case 'mapAOAnisotropy': + break; + case 'mapBump': + json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapBumpScale': + json.bumpScale = value; + break; + case 'mapBumpRepeat': + case 'mapBumpOffset': + case 'mapBumpWrap': + case 'mapBumpAnisotropy': + break; + case 'mapNormal': + json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapNormalFactor': + json.normalScale = value; + break; + case 'mapNormalRepeat': + case 'mapNormalOffset': + case 'mapNormalWrap': + case 'mapNormalAnisotropy': + break; + case 'mapSpecular': + json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapSpecularRepeat': + case 'mapSpecularOffset': + case 'mapSpecularWrap': + case 'mapSpecularAnisotropy': + break; + case 'mapMetalness': + json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapMetalnessRepeat': + case 'mapMetalnessOffset': + case 'mapMetalnessWrap': + case 'mapMetalnessAnisotropy': + break; + case 'mapRoughness': + json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapRoughnessRepeat': + case 'mapRoughnessOffset': + case 'mapRoughnessWrap': + case 'mapRoughnessAnisotropy': + break; + case 'mapAlpha': + json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy, textures, texturePath, crossOrigin ); + break; + case 'mapAlphaRepeat': + case 'mapAlphaOffset': + case 'mapAlphaWrap': + case 'mapAlphaAnisotropy': + break; + case 'flipSided': + json.side = THREE.BackSide; + break; + case 'doubleSided': + json.side = THREE.DoubleSide; + break; + case 'transparency': + console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' ); + json.opacity = value; + break; + case 'depthTest': + case 'depthWrite': + case 'colorWrite': + case 'opacity': + case 'reflectivity': + case 'transparent': + case 'visible': + case 'wireframe': + json[ name ] = value; + break; + case 'vertexColors': + if ( value === true ) json.vertexColors = THREE.VertexColors; + if ( value === 'face' ) json.vertexColors = THREE.FaceColors; + break; + default: + console.error( 'THREE.Loader.createMaterial: Unsupported', name, value ); + break; + + } + + } + + if ( json.type === 'MeshBasicMaterial' ) delete json.emissive; + if ( json.type !== 'MeshPhongMaterial' ) delete json.specular; + + if ( json.opacity < 1 ) json.transparent = true; + + _materialLoader.setTextures( textures ); + + return _materialLoader.parse( json ); + + } + + function loadTexture( path, repeat, offset, wrap, anisotropy, textures, texturePath, crossOrigin ) { + + var fullPath = texturePath + path; + var loader = THREE.Loader.Handlers.get( fullPath ); + + var texture; + + if ( loader !== null ) { + + texture = loader.load( fullPath ); + + } else { + + _textureLoader.setCrossOrigin( crossOrigin ); + texture = _textureLoader.load( fullPath ); + + } + + if ( repeat !== undefined ) { + + texture.repeat.fromArray( repeat ); + + if ( repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping; + if ( repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping; + + } + + if ( offset !== undefined ) { + + texture.offset.fromArray( offset ); + + } + + if ( wrap !== undefined ) { + + if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = THREE.RepeatWrapping; + if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = THREE.MirroredRepeatWrapping; + + if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = THREE.RepeatWrapping; + if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = THREE.MirroredRepeatWrapping; + + } + + if ( anisotropy !== undefined ) { + + texture.anisotropy = anisotropy; + + } + + var uuid = THREE.Math.generateUUID(); + + textures[ uuid ] = texture; + + return uuid; + + } + function parseModel( json, geometry ) { function isBitSet( value, position ) { @@ -561,7 +825,7 @@ THREE.LegacyJSONLoader = ( function () { } else { - var materials = THREE.Loader.prototype.initMaterials( json.materials, this.resourcePath || path, this.crossOrigin ); + var materials = initMaterials( json.materials, this.resourcePath || path, this.crossOrigin ); return { geometry: geometry, materials: materials }; diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/modifers/SimplifyModifier.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/modifers/SimplifyModifier.js index b67239cc..3e20c8d0 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/modifers/SimplifyModifier.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/modifers/SimplifyModifier.js @@ -1,4 +1,4 @@ -/* +/** * @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog * * Simplification Geometry Modifier diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/modifers/SubdivisionModifier.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/modifers/SubdivisionModifier.js index d12ca31f..1af8b0e6 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/modifers/SubdivisionModifier.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/modifers/SubdivisionModifier.js @@ -1,4 +1,4 @@ -/* +/** * @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog * @author centerionware / http://www.centerionware.com * diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/objects/Reflector.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/objects/Reflector.js index cbf05c9c..47fdc2bd 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/objects/Reflector.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/objects/Reflector.js @@ -170,9 +170,11 @@ THREE.Reflector = function ( geometry, options ) { // Restore viewport - if ( camera.isArrayCamera ) { + var viewport = camera.viewport; - renderer.state.viewport( camera.viewport ); + if ( viewport !== undefined ) { + + renderer.state.viewport( viewport ); } diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/objects/Refractor.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/objects/Refractor.js index c81043a4..37bc9661 100644 --- a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/objects/Refractor.js +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/objects/Refractor.js @@ -205,9 +205,11 @@ THREE.Refractor = function ( geometry, options ) { // restore viewport - if ( camera.isArrayCamera ) { + var viewport = camera.viewport; - renderer.state.viewport( camera.viewport ); + if ( viewport !== undefined ) { + + renderer.state.viewport( viewport ); } diff --git a/pom.xml b/pom.xml index d2805823..5e1f65ce 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.treblereel.gwt three4g-parent - 0.108-SNAPSHOT + 0.109-SNAPSHOT pom three4g-parent diff --git a/processor/pom.xml b/processor/pom.xml index 2ec74695..d4b8345a 100644 --- a/processor/pom.xml +++ b/processor/pom.xml @@ -5,7 +5,7 @@ org.treblereel.gwt three4g-parent - 0.108-SNAPSHOT + 0.109-SNAPSHOT ..