2018-08-01 21:34:58 +08:00

1596 lines
85 KiB
JavaScript

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('three')) :
typeof define === 'function' && define.amd ? define(['exports', 'three'], factory) :
(factory((global.BAS = {}),global.THREE));
}(this, (function (exports,three) { 'use strict';
function BaseAnimationMaterial(parameters, uniforms) {
three.ShaderMaterial.call(this);
var uniformValues = parameters.uniformValues;
delete parameters.uniformValues;
this.setValues(parameters);
this.uniforms = three.UniformsUtils.merge([uniforms, this.uniforms]);
this.setUniformValues(uniformValues);
if (uniformValues) {
uniformValues.map && (this.defines['USE_MAP'] = '');
uniformValues.normalMap && (this.defines['USE_NORMALMAP'] = '');
uniformValues.envMap && (this.defines['USE_ENVMAP'] = '');
uniformValues.aoMap && (this.defines['USE_AOMAP'] = '');
uniformValues.specularMap && (this.defines['USE_SPECULARMAP'] = '');
uniformValues.alphaMap && (this.defines['USE_ALPHAMAP'] = '');
uniformValues.lightMap && (this.defines['USE_LIGHTMAP'] = '');
uniformValues.emissiveMap && (this.defines['USE_EMISSIVEMAP'] = '');
uniformValues.bumpMap && (this.defines['USE_BUMPMAP'] = '');
uniformValues.displacementMap && (this.defines['USE_DISPLACEMENTMAP'] = '');
uniformValues.roughnessMap && (this.defines['USE_DISPLACEMENTMAP'] = '');
uniformValues.roughnessMap && (this.defines['USE_ROUGHNESSMAP'] = '');
uniformValues.metalnessMap && (this.defines['USE_METALNESSMAP'] = '');
if (uniformValues.envMap) {
this.defines['USE_ENVMAP'] = '';
var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
switch (uniformValues.envMap.mapping) {
case three.CubeReflectionMapping:
case three.CubeRefractionMapping:
envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
break;
case three.CubeUVReflectionMapping:
case three.CubeUVRefractionMapping:
envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
break;
case three.EquirectangularReflectionMapping:
case three.EquirectangularRefractionMapping:
envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
break;
case three.SphericalReflectionMapping:
envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
break;
}
switch (uniformValues.envMap.mapping) {
case three.CubeRefractionMapping:
case three.EquirectangularRefractionMapping:
envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
break;
}
switch (uniformValues.combine) {
case three.MixOperation:
envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
break;
case three.AddOperation:
envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
break;
case three.MultiplyOperation:
default:
envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
break;
}
this.defines[envMapTypeDefine] = '';
this.defines[envMapBlendingDefine] = '';
this.defines[envMapModeDefine] = '';
}
}
}
BaseAnimationMaterial.prototype = Object.assign(Object.create(three.ShaderMaterial.prototype), {
constructor: BaseAnimationMaterial,
setUniformValues: function setUniformValues(values) {
var _this = this;
if (!values) return;
var keys = Object.keys(values);
keys.forEach(function (key) {
key in _this.uniforms && (_this.uniforms[key].value = values[key]);
});
},
stringifyChunk: function stringifyChunk(name) {
var value = void 0;
if (!this[name]) {
value = '';
} else if (typeof this[name] === 'string') {
value = this[name];
} else {
value = this[name].join('\n');
}
return value;
}
});
/**
* Extends THREE.MeshBasicMaterial with custom shader chunks.
*
* @see http://three-bas-examples.surge.sh/examples/materials_basic/
*
* @param {Object} parameters Object containing material properties and custom shader chunks.
* @constructor
*/
function BasicAnimationMaterial(parameters) {
this.varyingParameters = [];
this.vertexParameters = [];
this.vertexFunctions = [];
this.vertexInit = [];
this.vertexNormal = [];
this.vertexPosition = [];
this.vertexColor = [];
this.vertexPostMorph = [];
this.vertexPostSkinning = [];
this.fragmentFunctions = [];
this.fragmentParameters = [];
this.fragmentInit = [];
this.fragmentMap = [];
this.fragmentDiffuse = [];
BaseAnimationMaterial.call(this, parameters, three.ShaderLib['basic'].uniforms);
this.lights = false;
this.vertexShader = this.concatVertexShader();
this.fragmentShader = this.concatFragmentShader();
}
BasicAnimationMaterial.prototype = Object.create(BaseAnimationMaterial.prototype);
BasicAnimationMaterial.prototype.constructor = BasicAnimationMaterial;
BasicAnimationMaterial.prototype.concatVertexShader = function () {
return '\n #include <common>\n #include <uv_pars_vertex>\n #include <uv2_pars_vertex>\n #include <envmap_pars_vertex>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n \n ' + this.stringifyChunk('vertexParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('vertexFunctions') + '\n \n void main() {\n\n ' + this.stringifyChunk('vertexInit') + '\n \n #include <uv_vertex>\n #include <uv2_vertex>\n #include <color_vertex>\n #include <skinbase_vertex>\n \n #ifdef USE_ENVMAP\n \n #include <beginnormal_vertex>\n \n ' + this.stringifyChunk('vertexNormal') + '\n \n #include <morphnormal_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n \n #endif\n \n #include <begin_vertex>\n \n ' + this.stringifyChunk('vertexPosition') + '\n ' + this.stringifyChunk('vertexColor') + '\n \n #include <morphtarget_vertex>\n \n ' + this.stringifyChunk('vertexPostMorph') + '\n \n #include <skinning_vertex>\n\n ' + this.stringifyChunk('vertexPostSkinning') + '\n\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n \n #include <worldpos_vertex>\n #include <clipping_planes_vertex>\n #include <envmap_vertex>\n #include <fog_vertex>\n }';
};
BasicAnimationMaterial.prototype.concatFragmentShader = function () {
return '\n uniform vec3 diffuse;\n uniform float opacity;\n \n ' + this.stringifyChunk('fragmentParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('fragmentFunctions') + '\n \n #ifndef FLAT_SHADED\n \n varying vec3 vNormal;\n \n #endif\n \n #include <common>\n #include <color_pars_fragment>\n #include <uv_pars_fragment>\n #include <uv2_pars_fragment>\n #include <map_pars_fragment>\n #include <alphamap_pars_fragment>\n #include <aomap_pars_fragment>\n #include <lightmap_pars_fragment>\n #include <envmap_pars_fragment>\n #include <fog_pars_fragment>\n #include <specularmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n \n void main() {\n \n ' + this.stringifyChunk('fragmentInit') + '\n \n #include <clipping_planes_fragment>\n\n vec4 diffuseColor = vec4( diffuse, opacity );\n\n ' + this.stringifyChunk('fragmentDiffuse') + '\n \n #include <logdepthbuf_fragment>\n \n ' + (this.stringifyChunk('fragmentMap') || '#include <map_fragment>') + '\n \n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <specularmap_fragment>\n \n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n \n // accumulation (baked indirect lighting only)\n #ifdef USE_LIGHTMAP\n \n reflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n \n #else\n \n reflectedLight.indirectDiffuse += vec3( 1.0 );\n \n #endif\n \n // modulation\n #include <aomap_fragment>\n \n reflectedLight.indirectDiffuse *= diffuseColor.rgb;\n \n vec3 outgoingLight = reflectedLight.indirectDiffuse;\n \n #include <envmap_fragment>\n \n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n \n #include <premultiplied_alpha_fragment>\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n #include <fog_fragment>\n }';
};
/**
* Extends THREE.MeshLambertMaterial with custom shader chunks.
*
* @see http://three-bas-examples.surge.sh/examples/materials_lambert/
*
* @param {Object} parameters Object containing material properties and custom shader chunks.
* @constructor
*/
function LambertAnimationMaterial(parameters) {
this.varyingParameters = [];
this.vertexFunctions = [];
this.vertexParameters = [];
this.vertexInit = [];
this.vertexNormal = [];
this.vertexPosition = [];
this.vertexColor = [];
this.vertexPostMorph = [];
this.vertexPostSkinning = [];
this.fragmentFunctions = [];
this.fragmentParameters = [];
this.fragmentInit = [];
this.fragmentMap = [];
this.fragmentDiffuse = [];
this.fragmentEmissive = [];
this.fragmentSpecular = [];
BaseAnimationMaterial.call(this, parameters, three.ShaderLib['lambert'].uniforms);
this.lights = true;
this.vertexShader = this.concatVertexShader();
this.fragmentShader = this.concatFragmentShader();
}
LambertAnimationMaterial.prototype = Object.create(BaseAnimationMaterial.prototype);
LambertAnimationMaterial.prototype.constructor = LambertAnimationMaterial;
LambertAnimationMaterial.prototype.concatVertexShader = function () {
return '\n #define LAMBERT\n\n varying vec3 vLightFront;\n \n #ifdef DOUBLE_SIDED\n \n varying vec3 vLightBack;\n \n #endif\n \n #include <common>\n #include <uv_pars_vertex>\n #include <uv2_pars_vertex>\n #include <envmap_pars_vertex>\n #include <bsdfs>\n #include <lights_pars_begin>\n #include <lights_pars_maps>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <shadowmap_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n \n ' + this.stringifyChunk('vertexParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('vertexFunctions') + '\n \n void main() {\n \n ' + this.stringifyChunk('vertexInit') + '\n \n #include <uv_vertex>\n #include <uv2_vertex>\n #include <color_vertex>\n \n #include <beginnormal_vertex>\n \n ' + this.stringifyChunk('vertexNormal') + '\n \n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n \n #include <begin_vertex>\n \n ' + this.stringifyChunk('vertexPosition') + '\n ' + this.stringifyChunk('vertexColor') + '\n \n #include <morphtarget_vertex>\n \n ' + this.stringifyChunk('vertexPostMorph') + '\n \n #include <skinning_vertex>\n\n ' + this.stringifyChunk('vertexPostSkinning') + '\n \n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n \n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <lights_lambert_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n }';
};
LambertAnimationMaterial.prototype.concatFragmentShader = function () {
return '\n uniform vec3 diffuse;\n uniform vec3 emissive;\n uniform float opacity;\n \n varying vec3 vLightFront;\n \n #ifdef DOUBLE_SIDED\n \n varying vec3 vLightBack;\n \n #endif\n \n #include <common>\n #include <packing>\n #include <dithering_pars_fragment>\n #include <color_pars_fragment>\n #include <uv_pars_fragment>\n #include <uv2_pars_fragment>\n #include <map_pars_fragment>\n #include <alphamap_pars_fragment>\n #include <aomap_pars_fragment>\n #include <lightmap_pars_fragment>\n #include <emissivemap_pars_fragment>\n #include <envmap_pars_fragment>\n #include <bsdfs>\n #include <lights_pars_begin>\n #include <lights_pars_maps>\n #include <fog_pars_fragment>\n #include <shadowmap_pars_fragment>\n #include <shadowmask_pars_fragment>\n #include <specularmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n \n ' + this.stringifyChunk('fragmentParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('fragmentFunctions') + '\n \n void main() {\n \n ' + this.stringifyChunk('fragmentInit') + '\n \n #include <clipping_planes_fragment>\n\n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n\t\n ' + this.stringifyChunk('fragmentDiffuse') + '\n \n #include <logdepthbuf_fragment>\n\n ' + (this.stringifyChunk('fragmentMap') || '#include <map_fragment>') + '\n\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <specularmap_fragment>\n\n ' + this.stringifyChunk('fragmentEmissive') + '\n\n #include <emissivemap_fragment>\n \n // accumulation\n reflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n \n #include <lightmap_fragment>\n \n reflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n \n #ifdef DOUBLE_SIDED\n \n reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n \n #else\n \n reflectedLight.directDiffuse = vLightFront;\n \n #endif\n \n reflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n \n // modulation\n #include <aomap_fragment>\n \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n \n #include <envmap_fragment>\n \n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n \n #include <tonemapping_fragment>\n #include <encodings_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n }';
};
/**
* Extends THREE.MeshPhongMaterial with custom shader chunks.
*
* @see http://three-bas-examples.surge.sh/examples/materials_phong/
*
* @param {Object} parameters Object containing material properties and custom shader chunks.
* @constructor
*/
function PhongAnimationMaterial(parameters) {
this.varyingParameters = [];
this.vertexFunctions = [];
this.vertexParameters = [];
this.vertexInit = [];
this.vertexNormal = [];
this.vertexPosition = [];
this.vertexColor = [];
this.fragmentFunctions = [];
this.fragmentParameters = [];
this.fragmentInit = [];
this.fragmentMap = [];
this.fragmentDiffuse = [];
this.fragmentEmissive = [];
this.fragmentSpecular = [];
BaseAnimationMaterial.call(this, parameters, three.ShaderLib['phong'].uniforms);
this.lights = true;
this.vertexShader = this.concatVertexShader();
this.fragmentShader = this.concatFragmentShader();
}
PhongAnimationMaterial.prototype = Object.create(BaseAnimationMaterial.prototype);
PhongAnimationMaterial.prototype.constructor = PhongAnimationMaterial;
PhongAnimationMaterial.prototype.concatVertexShader = function () {
return '\n #define PHONG\n\n varying vec3 vViewPosition;\n \n #ifndef FLAT_SHADED\n \n varying vec3 vNormal;\n \n #endif\n \n #include <common>\n #include <uv_pars_vertex>\n #include <uv2_pars_vertex>\n #include <displacementmap_pars_vertex>\n #include <envmap_pars_vertex>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <shadowmap_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n \n ' + this.stringifyChunk('vertexParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('vertexFunctions') + '\n \n void main() {\n \n ' + this.stringifyChunk('vertexInit') + '\n \n #include <uv_vertex>\n #include <uv2_vertex>\n #include <color_vertex>\n \n #include <beginnormal_vertex>\n \n ' + this.stringifyChunk('vertexNormal') + '\n \n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n \n #ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED\n \n vNormal = normalize( transformedNormal );\n \n #endif\n \n #include <begin_vertex>\n \n ' + this.stringifyChunk('vertexPosition') + '\n ' + this.stringifyChunk('vertexColor') + '\n \n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n \n vViewPosition = - mvPosition.xyz;\n \n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n }';
};
PhongAnimationMaterial.prototype.concatFragmentShader = function () {
return '\n #define PHONG\n\n uniform vec3 diffuse;\n uniform vec3 emissive;\n uniform vec3 specular;\n uniform float shininess;\n uniform float opacity;\n \n #include <common>\n #include <packing>\n #include <dithering_pars_fragment>\n #include <color_pars_fragment>\n #include <uv_pars_fragment>\n #include <uv2_pars_fragment>\n #include <map_pars_fragment>\n #include <alphamap_pars_fragment>\n #include <aomap_pars_fragment>\n #include <lightmap_pars_fragment>\n #include <emissivemap_pars_fragment>\n #include <envmap_pars_fragment>\n #include <gradientmap_pars_fragment>\n #include <fog_pars_fragment>\n #include <bsdfs>\n #include <lights_pars_begin>\n #include <lights_pars_maps>\n #include <lights_phong_pars_fragment>\n #include <shadowmap_pars_fragment>\n #include <bumpmap_pars_fragment>\n #include <normalmap_pars_fragment>\n #include <specularmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n \n ' + this.stringifyChunk('fragmentParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('fragmentFunctions') + '\n \n void main() {\n \n ' + this.stringifyChunk('fragmentInit') + '\n \n #include <clipping_planes_fragment>\n \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n \n ' + this.stringifyChunk('fragmentDiffuse') + '\n \n #include <logdepthbuf_fragment>\n\n ' + (this.stringifyChunk('fragmentMap') || '#include <map_fragment>') + '\n\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <specularmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n \n ' + this.stringifyChunk('fragmentEmissive') + '\n \n #include <emissivemap_fragment>\n \n // accumulation\n #include <lights_phong_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n \n ' + this.stringifyChunk('fragmentSpecular') + '\n \n // modulation\n #include <aomap_fragment>\n \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n \n #include <envmap_fragment>\n \n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n \n #include <tonemapping_fragment>\n #include <encodings_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n \n }';
};
/**
* Extends THREE.MeshStandardMaterial with custom shader chunks.
*
* @see http://three-bas-examples.surge.sh/examples/materials_standard/
*
* @param {Object} parameters Object containing material properties and custom shader chunks.
* @constructor
*/
function StandardAnimationMaterial(parameters) {
this.varyingParameters = [];
this.vertexFunctions = [];
this.vertexParameters = [];
this.vertexInit = [];
this.vertexNormal = [];
this.vertexPosition = [];
this.vertexColor = [];
this.vertexPostMorph = [];
this.vertexPostSkinning = [];
this.fragmentFunctions = [];
this.fragmentParameters = [];
this.fragmentInit = [];
this.fragmentMap = [];
this.fragmentDiffuse = [];
this.fragmentRoughness = [];
this.fragmentMetalness = [];
this.fragmentEmissive = [];
BaseAnimationMaterial.call(this, parameters, three.ShaderLib['standard'].uniforms);
this.lights = true;
this.vertexShader = this.concatVertexShader();
this.fragmentShader = this.concatFragmentShader();
}
StandardAnimationMaterial.prototype = Object.create(BaseAnimationMaterial.prototype);
StandardAnimationMaterial.prototype.constructor = StandardAnimationMaterial;
StandardAnimationMaterial.prototype.concatVertexShader = function () {
return '\n #define PHYSICAL\n\n varying vec3 vViewPosition;\n \n #ifndef FLAT_SHADED\n \n varying vec3 vNormal;\n \n #endif\n \n #include <common>\n #include <uv_pars_vertex>\n #include <uv2_pars_vertex>\n #include <displacementmap_pars_vertex>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <shadowmap_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n \n ' + this.stringifyChunk('vertexParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('vertexFunctions') + '\n \n void main() {\n\n ' + this.stringifyChunk('vertexInit') + '\n\n #include <uv_vertex>\n #include <uv2_vertex>\n #include <color_vertex>\n \n #include <beginnormal_vertex>\n \n ' + this.stringifyChunk('vertexNormal') + '\n \n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n \n #ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED\n \n vNormal = normalize( transformedNormal );\n \n #endif\n \n #include <begin_vertex>\n \n ' + this.stringifyChunk('vertexPosition') + '\n ' + this.stringifyChunk('vertexColor') + '\n \n #include <morphtarget_vertex>\n \n ' + this.stringifyChunk('vertexPostMorph') + '\n \n #include <skinning_vertex>\n\n ' + this.stringifyChunk('vertexPostSkinning') + '\n \n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n \n vViewPosition = - mvPosition.xyz;\n \n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n }';
};
StandardAnimationMaterial.prototype.concatFragmentShader = function () {
return '\n #define PHYSICAL\n \n uniform vec3 diffuse;\n uniform vec3 emissive;\n uniform float roughness;\n uniform float metalness;\n uniform float opacity;\n \n #ifndef STANDARD\n uniform float clearCoat;\n uniform float clearCoatRoughness;\n #endif\n \n varying vec3 vViewPosition;\n \n #ifndef FLAT_SHADED\n \n varying vec3 vNormal;\n \n #endif\n \n #include <common>\n #include <packing>\n #include <dithering_pars_fragment>\n #include <color_pars_fragment>\n #include <uv_pars_fragment>\n #include <uv2_pars_fragment>\n #include <map_pars_fragment>\n #include <alphamap_pars_fragment>\n #include <aomap_pars_fragment>\n #include <lightmap_pars_fragment>\n #include <emissivemap_pars_fragment>\n #include <envmap_pars_fragment>\n #include <fog_pars_fragment>\n #include <bsdfs>\n #include <cube_uv_reflection_fragment>\n #include <lights_pars_begin>\n #include <lights_pars_maps>\n #include <lights_physical_pars_fragment>\n #include <shadowmap_pars_fragment>\n #include <bumpmap_pars_fragment>\n #include <normalmap_pars_fragment>\n #include <roughnessmap_pars_fragment>\n #include <metalnessmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n \n ' + this.stringifyChunk('fragmentParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('fragmentFunctions') + '\n \n void main() {\n \n ' + this.stringifyChunk('fragmentInit') + '\n \n #include <clipping_planes_fragment>\n \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n \n ' + this.stringifyChunk('fragmentDiffuse') + '\n \n #include <logdepthbuf_fragment>\n\n ' + (this.stringifyChunk('fragmentMap') || '#include <map_fragment>') + '\n\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n \n float roughnessFactor = roughness;\n ' + this.stringifyChunk('fragmentRoughness') + '\n #ifdef USE_ROUGHNESSMAP\n \n vec4 texelRoughness = texture2D( roughnessMap, vUv );\n \n // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n roughnessFactor *= texelRoughness.g;\n \n #endif\n \n float metalnessFactor = metalness;\n ' + this.stringifyChunk('fragmentMetalness') + '\n #ifdef USE_METALNESSMAP\n \n vec4 texelMetalness = texture2D( metalnessMap, vUv );\n metalnessFactor *= texelMetalness.b;\n \n #endif\n \n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n \n ' + this.stringifyChunk('fragmentEmissive') + '\n \n #include <emissivemap_fragment>\n \n // accumulation\n #include <lights_physical_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n \n // modulation\n #include <aomap_fragment>\n \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n \n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n \n #include <tonemapping_fragment>\n #include <encodings_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n \n }';
};
/**
* Extends THREE.PointsMaterial with custom shader chunks.
*
* @param {Object} parameters Object containing material properties and custom shader chunks.
* @constructor
*/
function PointsAnimationMaterial(parameters) {
this.varyingParameters = [];
this.vertexFunctions = [];
this.vertexParameters = [];
this.vertexInit = [];
this.vertexPosition = [];
this.vertexColor = [];
this.fragmentFunctions = [];
this.fragmentParameters = [];
this.fragmentInit = [];
this.fragmentMap = [];
this.fragmentDiffuse = [];
// use fragment shader to shape to point, reference: https://thebookofshaders.com/07/
this.fragmentShape = [];
BaseAnimationMaterial.call(this, parameters, three.ShaderLib['points'].uniforms);
this.vertexShader = this.concatVertexShader();
this.fragmentShader = this.concatFragmentShader();
}
PointsAnimationMaterial.prototype = Object.create(BaseAnimationMaterial.prototype);
PointsAnimationMaterial.prototype.constructor = PointsAnimationMaterial;
PointsAnimationMaterial.prototype.concatVertexShader = function () {
return '\n uniform float size;\n uniform float scale;\n \n #include <common>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <shadowmap_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n \n ' + this.stringifyChunk('vertexParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('vertexFunctions') + '\n \n void main() {\n \n ' + this.stringifyChunk('vertexInit') + '\n \n #include <color_vertex>\n #include <begin_vertex>\n \n ' + this.stringifyChunk('vertexPosition') + '\n ' + this.stringifyChunk('vertexColor') + '\n \n #include <project_vertex>\n \n #ifdef USE_SIZEATTENUATION\n gl_PointSize = size * ( scale / - mvPosition.z );\n #else\n gl_PointSize = size;\n #endif\n \n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n }';
};
PointsAnimationMaterial.prototype.concatFragmentShader = function () {
return '\n uniform vec3 diffuse;\n uniform float opacity;\n \n #include <common>\n #include <packing>\n #include <color_pars_fragment>\n #include <map_particle_pars_fragment>\n #include <fog_pars_fragment>\n #include <shadowmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n \n ' + this.stringifyChunk('fragmentParameters') + '\n ' + this.stringifyChunk('varyingParameters') + '\n ' + this.stringifyChunk('fragmentFunctions') + '\n \n void main() {\n \n ' + this.stringifyChunk('fragmentInit') + '\n \n #include <clipping_planes_fragment>\n \n vec3 outgoingLight = vec3( 0.0 );\n vec4 diffuseColor = vec4( diffuse, opacity );\n \n ' + this.stringifyChunk('fragmentDiffuse') + '\n \n #include <logdepthbuf_fragment>\n\n ' + (this.stringifyChunk('fragmentMap') || '#include <map_particle_fragment>') + '\n\n #include <color_fragment>\n #include <alphatest_fragment>\n \n outgoingLight = diffuseColor.rgb;\n \n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n \n ' + this.stringifyChunk('fragmentShape') + '\n \n #include <premultiplied_alpha_fragment>\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n #include <fog_fragment>\n }';
};
function DepthAnimationMaterial(parameters) {
this.depthPacking = three.RGBADepthPacking;
this.clipping = true;
this.vertexFunctions = [];
this.vertexParameters = [];
this.vertexInit = [];
this.vertexPosition = [];
this.vertexPostMorph = [];
this.vertexPostSkinning = [];
BaseAnimationMaterial.call(this, parameters);
this.uniforms = three.UniformsUtils.merge([three.ShaderLib['depth'].uniforms, this.uniforms]);
this.vertexShader = this.concatVertexShader();
this.fragmentShader = three.ShaderLib['depth'].fragmentShader;
}
DepthAnimationMaterial.prototype = Object.create(BaseAnimationMaterial.prototype);
DepthAnimationMaterial.prototype.constructor = DepthAnimationMaterial;
DepthAnimationMaterial.prototype.concatVertexShader = function () {
return '\n #include <common>\n #include <uv_pars_vertex>\n #include <displacementmap_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n \n ' + this.stringifyChunk('vertexParameters') + '\n ' + this.stringifyChunk('vertexFunctions') + '\n \n void main() {\n \n ' + this.stringifyChunk('vertexInit') + '\n \n #include <uv_vertex>\n \n #include <skinbase_vertex>\n \n #ifdef USE_DISPLACEMENTMAP\n \n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinnormal_vertex>\n \n #endif\n \n #include <begin_vertex>\n \n ' + this.stringifyChunk('vertexPosition') + '\n\n #include <morphtarget_vertex>\n \n ' + this.stringifyChunk('vertexPostMorph') + '\n \n #include <skinning_vertex>\n\n ' + this.stringifyChunk('vertexPostSkinning') + '\n \n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n }';
};
function DistanceAnimationMaterial(parameters) {
this.depthPacking = three.RGBADepthPacking;
this.clipping = true;
this.vertexFunctions = [];
this.vertexParameters = [];
this.vertexInit = [];
this.vertexPosition = [];
this.vertexPostMorph = [];
this.vertexPostSkinning = [];
BaseAnimationMaterial.call(this, parameters);
this.uniforms = three.UniformsUtils.merge([three.ShaderLib['distanceRGBA'].uniforms, this.uniforms]);
this.vertexShader = this.concatVertexShader();
this.fragmentShader = three.ShaderLib['distanceRGBA'].fragmentShader;
}
DistanceAnimationMaterial.prototype = Object.create(BaseAnimationMaterial.prototype);
DistanceAnimationMaterial.prototype.constructor = DistanceAnimationMaterial;
DistanceAnimationMaterial.prototype.concatVertexShader = function () {
return '\n #define DISTANCE\n\n varying vec3 vWorldPosition;\n \n #include <common>\n #include <uv_pars_vertex>\n #include <displacementmap_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <clipping_planes_pars_vertex>\n \n ' + this.stringifyChunk('vertexParameters') + '\n ' + this.stringifyChunk('vertexFunctions') + '\n \n void main() {\n\n ' + this.stringifyChunk('vertexInit') + '\n \n #include <uv_vertex>\n \n #include <skinbase_vertex>\n \n #ifdef USE_DISPLACEMENTMAP\n \n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinnormal_vertex>\n \n #endif\n \n #include <begin_vertex>\n \n ' + this.stringifyChunk('vertexPosition') + '\n\n #include <morphtarget_vertex>\n \n ' + this.stringifyChunk('vertexPostMorph') + '\n \n #include <skinning_vertex>\n\n ' + this.stringifyChunk('vertexPostSkinning') + '\n \n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <worldpos_vertex>\n #include <clipping_planes_vertex>\n \n vWorldPosition = worldPosition.xyz;\n \n }';
};
/**
* A BufferGeometry where a 'prefab' geometry is repeated a number of times.
*
* @param {Geometry|BufferGeometry} prefab The Geometry instance to repeat.
* @param {Number} count The number of times to repeat the geometry.
* @constructor
*/
function PrefabBufferGeometry(prefab, count) {
three.BufferGeometry.call(this);
/**
* A reference to the prefab geometry used to create this instance.
* @type {Geometry|BufferGeometry}
*/
this.prefabGeometry = prefab;
this.isPrefabBufferGeometry = prefab.isBufferGeometry;
/**
* Number of prefabs.
* @type {Number}
*/
this.prefabCount = count;
/**
* Number of vertices of the prefab.
* @type {Number}
*/
if (this.isPrefabBufferGeometry) {
this.prefabVertexCount = prefab.attributes.position.count;
} else {
this.prefabVertexCount = prefab.vertices.length;
}
this.bufferIndices();
this.bufferPositions();
}
PrefabBufferGeometry.prototype = Object.create(three.BufferGeometry.prototype);
PrefabBufferGeometry.prototype.constructor = PrefabBufferGeometry;
PrefabBufferGeometry.prototype.bufferIndices = function () {
var prefabIndices = [];
var prefabIndexCount = void 0;
if (this.isPrefabBufferGeometry) {
if (this.prefabGeometry.index) {
prefabIndexCount = this.prefabGeometry.index.count;
prefabIndices = this.prefabGeometry.index.array;
} else {
prefabIndexCount = this.prefabVertexCount;
for (var i = 0; i < prefabIndexCount; i++) {
prefabIndices.push(i);
}
}
} else {
var prefabFaceCount = this.prefabGeometry.faces.length;
prefabIndexCount = prefabFaceCount * 3;
for (var _i = 0; _i < prefabFaceCount; _i++) {
var face = this.prefabGeometry.faces[_i];
prefabIndices.push(face.a, face.b, face.c);
}
}
var indexBuffer = new Uint32Array(this.prefabCount * prefabIndexCount);
this.setIndex(new three.BufferAttribute(indexBuffer, 1));
for (var _i2 = 0; _i2 < this.prefabCount; _i2++) {
for (var k = 0; k < prefabIndexCount; k++) {
indexBuffer[_i2 * prefabIndexCount + k] = prefabIndices[k] + _i2 * this.prefabVertexCount;
}
}
};
PrefabBufferGeometry.prototype.bufferPositions = function () {
var positionBuffer = this.createAttribute('position', 3).array;
if (this.isPrefabBufferGeometry) {
var positions = this.prefabGeometry.attributes.position.array;
for (var i = 0, offset = 0; i < this.prefabCount; i++) {
for (var j = 0; j < this.prefabVertexCount; j++, offset += 3) {
positionBuffer[offset] = positions[j * 3];
positionBuffer[offset + 1] = positions[j * 3 + 1];
positionBuffer[offset + 2] = positions[j * 3 + 2];
}
}
} else {
for (var _i3 = 0, _offset = 0; _i3 < this.prefabCount; _i3++) {
for (var _j = 0; _j < this.prefabVertexCount; _j++, _offset += 3) {
var prefabVertex = this.prefabGeometry.vertices[_j];
positionBuffer[_offset] = prefabVertex.x;
positionBuffer[_offset + 1] = prefabVertex.y;
positionBuffer[_offset + 2] = prefabVertex.z;
}
}
}
};
/**
* Creates a BufferAttribute with UV coordinates.
*/
PrefabBufferGeometry.prototype.bufferUvs = function () {
var prefabUvs = [];
if (this.isPrefabBufferGeometry) {
var uv = this.prefabGeometry.attributes.uv.array;
for (var i = 0; i < this.prefabVertexCount; i++) {
prefabUvs.push(new three.Vector2(uv[i * 2], uv[i * 2 + 1]));
}
} else {
var prefabFaceCount = this.prefabGeometry.faces.length;
for (var _i4 = 0; _i4 < prefabFaceCount; _i4++) {
var face = this.prefabGeometry.faces[_i4];
var _uv = this.prefabGeometry.faceVertexUvs[0][_i4];
prefabUvs[face.a] = _uv[0];
prefabUvs[face.b] = _uv[1];
prefabUvs[face.c] = _uv[2];
}
}
var uvBuffer = this.createAttribute('uv', 2);
for (var _i5 = 0, offset = 0; _i5 < this.prefabCount; _i5++) {
for (var j = 0; j < this.prefabVertexCount; j++, offset += 2) {
var prefabUv = prefabUvs[j];
uvBuffer.array[offset] = prefabUv.x;
uvBuffer.array[offset + 1] = prefabUv.y;
}
}
};
/**
* Creates a BufferAttribute on this geometry instance.
*
* @param {String} name Name of the attribute.
* @param {Number} itemSize Number of floats per vertex (typically 1, 2, 3 or 4).
* @param {function=} factory Function that will be called for each prefab upon creation. Accepts 3 arguments: data[], index and prefabCount. Calls setPrefabData.
*
* @returns {BufferAttribute}
*/
PrefabBufferGeometry.prototype.createAttribute = function (name, itemSize, factory) {
var buffer = new Float32Array(this.prefabCount * this.prefabVertexCount * itemSize);
var attribute = new three.BufferAttribute(buffer, itemSize);
this.addAttribute(name, attribute);
if (factory) {
var data = [];
for (var i = 0; i < this.prefabCount; i++) {
factory(data, i, this.prefabCount);
this.setPrefabData(attribute, i, data);
}
}
return attribute;
};
/**
* Sets data for all vertices of a prefab at a given index.
* Usually called in a loop.
*
* @param {String|BufferAttribute} attribute The attribute or attribute name where the data is to be stored.
* @param {Number} prefabIndex Index of the prefab in the buffer geometry.
* @param {Array} data Array of data. Length should be equal to item size of the attribute.
*/
PrefabBufferGeometry.prototype.setPrefabData = function (attribute, prefabIndex, data) {
attribute = typeof attribute === 'string' ? this.attributes[attribute] : attribute;
var offset = prefabIndex * this.prefabVertexCount * attribute.itemSize;
for (var i = 0; i < this.prefabVertexCount; i++) {
for (var j = 0; j < attribute.itemSize; j++) {
attribute.array[offset++] = data[j];
}
}
};
/**
* A BufferGeometry where a 'prefab' geometry array is repeated a number of times.
*
* @param {Array} prefabs An array with Geometry instances to repeat.
* @param {Number} repeatCount The number of times to repeat the array of Geometries.
* @constructor
*/
function MultiPrefabBufferGeometry(prefabs, repeatCount) {
three.BufferGeometry.call(this);
if (Array.isArray(prefabs)) {
this.prefabGeometries = prefabs;
} else {
this.prefabGeometries = [prefabs];
}
this.prefabGeometriesCount = this.prefabGeometries.length;
/**
* Number of prefabs.
* @type {Number}
*/
this.prefabCount = repeatCount * this.prefabGeometriesCount;
/**
* How often the prefab array is repeated.
* @type {Number}
*/
this.repeatCount = repeatCount;
/**
* Array of vertex counts per prefab.
* @type {Array}
*/
this.prefabVertexCounts = this.prefabGeometries.map(function (p) {
return p.isBufferGeometry ? p.attributes.position.count : p.vertices.length;
});
/**
* Total number of vertices for one repetition of the prefabs
* @type {number}
*/
this.repeatVertexCount = this.prefabVertexCounts.reduce(function (r, v) {
return r + v;
}, 0);
this.bufferIndices();
this.bufferPositions();
}
MultiPrefabBufferGeometry.prototype = Object.create(three.BufferGeometry.prototype);
MultiPrefabBufferGeometry.prototype.constructor = MultiPrefabBufferGeometry;
MultiPrefabBufferGeometry.prototype.bufferIndices = function () {
var repeatIndexCount = 0;
this.prefabIndices = this.prefabGeometries.map(function (geometry) {
var indices = [];
if (geometry.isBufferGeometry) {
if (geometry.index) {
indices = geometry.index.array;
} else {
for (var i = 0; i < geometry.attributes.position.count; i++) {
indices.push(i);
}
}
} else {
for (var _i = 0; _i < geometry.faces.length; _i++) {
var face = geometry.faces[_i];
indices.push(face.a, face.b, face.c);
}
}
repeatIndexCount += indices.length;
return indices;
});
var indexBuffer = new Uint32Array(repeatIndexCount * this.repeatCount);
var indexOffset = 0;
var prefabOffset = 0;
for (var i = 0; i < this.prefabCount; i++) {
var index = i % this.prefabGeometriesCount;
var indices = this.prefabIndices[index];
var vertexCount = this.prefabVertexCounts[index];
for (var j = 0; j < indices.length; j++) {
indexBuffer[indexOffset++] = indices[j] + prefabOffset;
}
prefabOffset += vertexCount;
}
this.setIndex(new three.BufferAttribute(indexBuffer, 1));
};
MultiPrefabBufferGeometry.prototype.bufferPositions = function () {
var _this = this;
var positionBuffer = this.createAttribute('position', 3).array;
var prefabPositions = this.prefabGeometries.map(function (geometry, i) {
var positions = void 0;
if (geometry.isBufferGeometry) {
positions = geometry.attributes.position.array;
} else {
var vertexCount = _this.prefabVertexCounts[i];
positions = [];
for (var j = 0, offset = 0; j < vertexCount; j++) {
var prefabVertex = geometry.vertices[j];
positions[offset++] = prefabVertex.x;
positions[offset++] = prefabVertex.y;
positions[offset++] = prefabVertex.z;
}
}
return positions;
});
for (var i = 0, offset = 0; i < this.prefabCount; i++) {
var index = i % this.prefabGeometries.length;
var vertexCount = this.prefabVertexCounts[index];
var positions = prefabPositions[index];
for (var j = 0; j < vertexCount; j++) {
positionBuffer[offset++] = positions[j * 3];
positionBuffer[offset++] = positions[j * 3 + 1];
positionBuffer[offset++] = positions[j * 3 + 2];
}
}
};
/**
* Creates a BufferAttribute with UV coordinates.
*/
MultiPrefabBufferGeometry.prototype.bufferUvs = function () {
var _this2 = this;
var uvBuffer = this.createAttribute('uv', 2).array;
var prefabUvs = this.prefabGeometries.map(function (geometry, i) {
var uvs = void 0;
if (geometry.isBufferGeometry) {
if (!geometry.attributes.uv) {
console.error('No UV found in prefab geometry', geometry);
}
uvs = geometry.attributes.uv.array;
} else {
var prefabFaceCount = _this2.prefabIndices[i].length / 3;
var uvObjects = [];
for (var j = 0; j < prefabFaceCount; j++) {
var face = geometry.faces[j];
var uv = geometry.faceVertexUvs[0][j];
uvObjects[face.a] = uv[0];
uvObjects[face.b] = uv[1];
uvObjects[face.c] = uv[2];
}
uvs = [];
for (var k = 0; k < uvObjects.length; k++) {
uvs[k * 2] = uvObjects[k].x;
uvs[k * 2 + 1] = uvObjects[k].y;
}
}
return uvs;
});
for (var i = 0, offset = 0; i < this.prefabCount; i++) {
var index = i % this.prefabGeometries.length;
var vertexCount = this.prefabVertexCounts[index];
var uvs = prefabUvs[index];
for (var j = 0; j < vertexCount; j++) {
uvBuffer[offset++] = uvs[j * 2];
uvBuffer[offset++] = uvs[j * 2 + 1];
}
}
};
/**
* Creates a BufferAttribute on this geometry instance.
*
* @param {String} name Name of the attribute.
* @param {Number} itemSize Number of floats per vertex (typically 1, 2, 3 or 4).
* @param {function=} factory Function that will be called for each prefab upon creation. Accepts 3 arguments: data[], index and prefabCount. Calls setPrefabData.
*
* @returns {BufferAttribute}
*/
MultiPrefabBufferGeometry.prototype.createAttribute = function (name, itemSize, factory) {
var buffer = new Float32Array(this.repeatCount * this.repeatVertexCount * itemSize);
var attribute = new three.BufferAttribute(buffer, itemSize);
this.addAttribute(name, attribute);
if (factory) {
var data = [];
for (var i = 0; i < this.prefabCount; i++) {
factory(data, i, this.prefabCount);
this.setPrefabData(attribute, i, data);
}
}
return attribute;
};
/**
* Sets data for all vertices of a prefab at a given index.
* Usually called in a loop.
*
* @param {String|BufferAttribute} attribute The attribute or attribute name where the data is to be stored.
* @param {Number} prefabIndex Index of the prefab in the buffer geometry.
* @param {Array} data Array of data. Length should be equal to item size of the attribute.
*/
MultiPrefabBufferGeometry.prototype.setPrefabData = function (attribute, prefabIndex, data) {
attribute = typeof attribute === 'string' ? this.attributes[attribute] : attribute;
var prefabGeometryIndex = prefabIndex % this.prefabGeometriesCount;
var prefabGeometryVertexCount = this.prefabVertexCounts[prefabGeometryIndex];
var whole = (prefabIndex / this.prefabGeometriesCount | 0) * this.prefabGeometriesCount;
var wholeOffset = whole * this.repeatVertexCount;
var part = prefabIndex - whole;
var partOffset = 0;
var i = 0;
while (i < part) {
partOffset += this.prefabVertexCounts[i++];
}
var offset = (wholeOffset + partOffset) * attribute.itemSize;
for (var _i2 = 0; _i2 < prefabGeometryVertexCount; _i2++) {
for (var j = 0; j < attribute.itemSize; j++) {
attribute.array[offset++] = data[j];
}
}
};
/**
* Collection of utility functions.
* @namespace
*/
var Utils = {
/**
* Duplicates vertices so each face becomes separate.
* Same as THREE.ExplodeModifier.
*
* @param {THREE.Geometry} geometry Geometry instance to modify.
*/
separateFaces: function separateFaces(geometry) {
var vertices = [];
for (var i = 0, il = geometry.faces.length; i < il; i++) {
var n = vertices.length;
var face = geometry.faces[i];
var a = face.a;
var b = face.b;
var c = face.c;
var va = geometry.vertices[a];
var vb = geometry.vertices[b];
var vc = geometry.vertices[c];
vertices.push(va.clone());
vertices.push(vb.clone());
vertices.push(vc.clone());
face.a = n;
face.b = n + 1;
face.c = n + 2;
}
geometry.vertices = vertices;
},
/**
* Compute the centroid (center) of a THREE.Face3.
*
* @param {THREE.Geometry} geometry Geometry instance the face is in.
* @param {THREE.Face3} face Face object from the THREE.Geometry.faces array
* @param {THREE.Vector3=} v Optional vector to store result in.
* @returns {THREE.Vector3}
*/
computeCentroid: function computeCentroid(geometry, face, v) {
var a = geometry.vertices[face.a];
var b = geometry.vertices[face.b];
var c = geometry.vertices[face.c];
v = v || new three.Vector3();
v.x = (a.x + b.x + c.x) / 3;
v.y = (a.y + b.y + c.y) / 3;
v.z = (a.z + b.z + c.z) / 3;
return v;
},
/**
* Get a random vector between box.min and box.max.
*
* @param {THREE.Box3} box THREE.Box3 instance.
* @param {THREE.Vector3=} v Optional vector to store result in.
* @returns {THREE.Vector3}
*/
randomInBox: function randomInBox(box, v) {
v = v || new three.Vector3();
v.x = three.Math.randFloat(box.min.x, box.max.x);
v.y = three.Math.randFloat(box.min.y, box.max.y);
v.z = three.Math.randFloat(box.min.z, box.max.z);
return v;
},
/**
* Get a random axis for quaternion rotation.
*
* @param {THREE.Vector3=} v Option vector to store result in.
* @returns {THREE.Vector3}
*/
randomAxis: function randomAxis(v) {
v = v || new three.Vector3();
v.x = three.Math.randFloatSpread(2.0);
v.y = three.Math.randFloatSpread(2.0);
v.z = three.Math.randFloatSpread(2.0);
v.normalize();
return v;
},
/**
* Create a THREE.BAS.DepthAnimationMaterial for shadows from a THREE.SpotLight or THREE.DirectionalLight by copying relevant shader chunks.
* Uniform values must be manually synced between the source material and the depth material.
*
* @see {@link http://three-bas-examples.surge.sh/examples/shadows/}
*
* @param {THREE.BAS.BaseAnimationMaterial} sourceMaterial Instance to get the shader chunks from.
* @returns {THREE.BAS.DepthAnimationMaterial}
*/
createDepthAnimationMaterial: function createDepthAnimationMaterial(sourceMaterial) {
return new DepthAnimationMaterial({
uniforms: sourceMaterial.uniforms,
defines: sourceMaterial.defines,
vertexFunctions: sourceMaterial.vertexFunctions,
vertexParameters: sourceMaterial.vertexParameters,
vertexInit: sourceMaterial.vertexInit,
vertexPosition: sourceMaterial.vertexPosition
});
},
/**
* Create a THREE.BAS.DistanceAnimationMaterial for shadows from a THREE.PointLight by copying relevant shader chunks.
* Uniform values must be manually synced between the source material and the distance material.
*
* @see {@link http://three-bas-examples.surge.sh/examples/shadows/}
*
* @param {THREE.BAS.BaseAnimationMaterial} sourceMaterial Instance to get the shader chunks from.
* @returns {THREE.BAS.DistanceAnimationMaterial}
*/
createDistanceAnimationMaterial: function createDistanceAnimationMaterial(sourceMaterial) {
return new DistanceAnimationMaterial({
uniforms: sourceMaterial.uniforms,
defines: sourceMaterial.defines,
vertexFunctions: sourceMaterial.vertexFunctions,
vertexParameters: sourceMaterial.vertexParameters,
vertexInit: sourceMaterial.vertexInit,
vertexPosition: sourceMaterial.vertexPosition
});
}
};
/**
* A THREE.BufferGeometry for animating individual faces of a THREE.Geometry.
*
* @param {THREE.Geometry} model The THREE.Geometry to base this geometry on.
* @param {Object=} options
* @param {Boolean=} options.computeCentroids If true, a centroids will be computed for each face and stored in THREE.BAS.ModelBufferGeometry.centroids.
* @param {Boolean=} options.localizeFaces If true, the positions for each face will be stored relative to the centroid. This is useful if you want to rotate or scale faces around their center.
* @constructor
*/
function ModelBufferGeometry(model, options) {
three.BufferGeometry.call(this);
/**
* A reference to the geometry used to create this instance.
* @type {THREE.Geometry}
*/
this.modelGeometry = model;
/**
* Number of faces of the model.
* @type {Number}
*/
this.faceCount = this.modelGeometry.faces.length;
/**
* Number of vertices of the model.
* @type {Number}
*/
this.vertexCount = this.modelGeometry.vertices.length;
options = options || {};
options.computeCentroids && this.computeCentroids();
this.bufferIndices();
this.bufferPositions(options.localizeFaces);
}
ModelBufferGeometry.prototype = Object.create(three.BufferGeometry.prototype);
ModelBufferGeometry.prototype.constructor = ModelBufferGeometry;
/**
* Computes a centroid for each face and stores it in THREE.BAS.ModelBufferGeometry.centroids.
*/
ModelBufferGeometry.prototype.computeCentroids = function () {
/**
* An array of centroids corresponding to the faces of the model.
*
* @type {Array}
*/
this.centroids = [];
for (var i = 0; i < this.faceCount; i++) {
this.centroids[i] = Utils.computeCentroid(this.modelGeometry, this.modelGeometry.faces[i]);
}
};
ModelBufferGeometry.prototype.bufferIndices = function () {
var indexBuffer = new Uint32Array(this.faceCount * 3);
this.setIndex(new three.BufferAttribute(indexBuffer, 1));
for (var i = 0, offset = 0; i < this.faceCount; i++, offset += 3) {
var face = this.modelGeometry.faces[i];
indexBuffer[offset] = face.a;
indexBuffer[offset + 1] = face.b;
indexBuffer[offset + 2] = face.c;
}
};
ModelBufferGeometry.prototype.bufferPositions = function (localizeFaces) {
var positionBuffer = this.createAttribute('position', 3).array;
var i = void 0,
offset = void 0;
if (localizeFaces === true) {
for (i = 0; i < this.faceCount; i++) {
var face = this.modelGeometry.faces[i];
var centroid = this.centroids ? this.centroids[i] : Utils.computeCentroid(this.modelGeometry, face);
var a = this.modelGeometry.vertices[face.a];
var b = this.modelGeometry.vertices[face.b];
var c = this.modelGeometry.vertices[face.c];
positionBuffer[face.a * 3] = a.x - centroid.x;
positionBuffer[face.a * 3 + 1] = a.y - centroid.y;
positionBuffer[face.a * 3 + 2] = a.z - centroid.z;
positionBuffer[face.b * 3] = b.x - centroid.x;
positionBuffer[face.b * 3 + 1] = b.y - centroid.y;
positionBuffer[face.b * 3 + 2] = b.z - centroid.z;
positionBuffer[face.c * 3] = c.x - centroid.x;
positionBuffer[face.c * 3 + 1] = c.y - centroid.y;
positionBuffer[face.c * 3 + 2] = c.z - centroid.z;
}
} else {
for (i = 0, offset = 0; i < this.vertexCount; i++, offset += 3) {
var vertex = this.modelGeometry.vertices[i];
positionBuffer[offset] = vertex.x;
positionBuffer[offset + 1] = vertex.y;
positionBuffer[offset + 2] = vertex.z;
}
}
};
/**
* Creates a THREE.BufferAttribute with UV coordinates.
*/
ModelBufferGeometry.prototype.bufferUVs = function () {
var uvBuffer = this.createAttribute('uv', 2).array;
for (var i = 0; i < this.faceCount; i++) {
var face = this.modelGeometry.faces[i];
var uv = void 0;
uv = this.modelGeometry.faceVertexUvs[0][i][0];
uvBuffer[face.a * 2] = uv.x;
uvBuffer[face.a * 2 + 1] = uv.y;
uv = this.modelGeometry.faceVertexUvs[0][i][1];
uvBuffer[face.b * 2] = uv.x;
uvBuffer[face.b * 2 + 1] = uv.y;
uv = this.modelGeometry.faceVertexUvs[0][i][2];
uvBuffer[face.c * 2] = uv.x;
uvBuffer[face.c * 2 + 1] = uv.y;
}
};
/**
* Creates two THREE.BufferAttributes: skinIndex and skinWeight. Both are required for skinning.
*/
ModelBufferGeometry.prototype.bufferSkinning = function () {
var skinIndexBuffer = this.createAttribute('skinIndex', 4).array;
var skinWeightBuffer = this.createAttribute('skinWeight', 4).array;
for (var i = 0; i < this.vertexCount; i++) {
var skinIndex = this.modelGeometry.skinIndices[i];
var skinWeight = this.modelGeometry.skinWeights[i];
skinIndexBuffer[i * 4] = skinIndex.x;
skinIndexBuffer[i * 4 + 1] = skinIndex.y;
skinIndexBuffer[i * 4 + 2] = skinIndex.z;
skinIndexBuffer[i * 4 + 3] = skinIndex.w;
skinWeightBuffer[i * 4] = skinWeight.x;
skinWeightBuffer[i * 4 + 1] = skinWeight.y;
skinWeightBuffer[i * 4 + 2] = skinWeight.z;
skinWeightBuffer[i * 4 + 3] = skinWeight.w;
}
};
/**
* Creates a THREE.BufferAttribute on this geometry instance.
*
* @param {String} name Name of the attribute.
* @param {int} itemSize Number of floats per vertex (typically 1, 2, 3 or 4).
* @param {function=} factory Function that will be called for each face upon creation. Accepts 3 arguments: data[], index and faceCount. Calls setFaceData.
*
* @returns {BufferAttribute}
*/
ModelBufferGeometry.prototype.createAttribute = function (name, itemSize, factory) {
var buffer = new Float32Array(this.vertexCount * itemSize);
var attribute = new three.BufferAttribute(buffer, itemSize);
this.addAttribute(name, attribute);
if (factory) {
var data = [];
for (var i = 0; i < this.faceCount; i++) {
factory(data, i, this.faceCount);
this.setFaceData(attribute, i, data);
}
}
return attribute;
};
/**
* Sets data for all vertices of a face at a given index.
* Usually called in a loop.
*
* @param {String|THREE.BufferAttribute} attribute The attribute or attribute name where the data is to be stored.
* @param {int} faceIndex Index of the face in the buffer geometry.
* @param {Array} data Array of data. Length should be equal to item size of the attribute.
*/
ModelBufferGeometry.prototype.setFaceData = function (attribute, faceIndex, data) {
attribute = typeof attribute === 'string' ? this.attributes[attribute] : attribute;
var offset = faceIndex * 3 * attribute.itemSize;
for (var i = 0; i < 3; i++) {
for (var j = 0; j < attribute.itemSize; j++) {
attribute.array[offset++] = data[j];
}
}
};
/**
* A THREE.BufferGeometry consists of points.
* @param {Number} count The number of points.
* @constructor
*/
function PointBufferGeometry(count) {
three.BufferGeometry.call(this);
/**
* Number of points.
* @type {Number}
*/
this.pointCount = count;
this.bufferPositions();
}
PointBufferGeometry.prototype = Object.create(three.BufferGeometry.prototype);
PointBufferGeometry.prototype.constructor = PointBufferGeometry;
PointBufferGeometry.prototype.bufferPositions = function () {
this.createAttribute('position', 3);
};
/**
* Creates a THREE.BufferAttribute on this geometry instance.
*
* @param {String} name Name of the attribute.
* @param {Number} itemSize Number of floats per vertex (typically 1, 2, 3 or 4).
* @param {function=} factory Function that will be called for each point upon creation. Accepts 3 arguments: data[], index and prefabCount. Calls setPointData.
*
* @returns {THREE.BufferAttribute}
*/
PointBufferGeometry.prototype.createAttribute = function (name, itemSize, factory) {
var buffer = new Float32Array(this.pointCount * itemSize);
var attribute = new three.BufferAttribute(buffer, itemSize);
this.addAttribute(name, attribute);
if (factory) {
var data = [];
for (var i = 0; i < this.pointCount; i++) {
factory(data, i, this.pointCount);
this.setPointData(attribute, i, data);
}
}
return attribute;
};
PointBufferGeometry.prototype.setPointData = function (attribute, pointIndex, data) {
attribute = typeof attribute === 'string' ? this.attributes[attribute] : attribute;
var offset = pointIndex * attribute.itemSize;
for (var j = 0; j < attribute.itemSize; j++) {
attribute.array[offset++] = data[j];
}
};
var catmull_rom_spline = "vec4 catmullRomSpline(vec4 p0, vec4 p1, vec4 p2, vec4 p3, float t, vec2 c) {\r\n vec4 v0 = (p2 - p0) * c.x;\r\n vec4 v1 = (p3 - p1) * c.y;\r\n float t2 = t * t;\r\n float t3 = t * t * t;\r\n\r\n return vec4((2.0 * p1 - 2.0 * p2 + v0 + v1) * t3 + (-3.0 * p1 + 3.0 * p2 - 2.0 * v0 - v1) * t2 + v0 * t + p1);\r\n}\r\nvec4 catmullRomSpline(vec4 p0, vec4 p1, vec4 p2, vec4 p3, float t) {\r\n return catmullRomSpline(p0, p1, p2, p3, t, vec2(0.5, 0.5));\r\n}\r\n\r\nvec3 catmullRomSpline(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t, vec2 c) {\r\n vec3 v0 = (p2 - p0) * c.x;\r\n vec3 v1 = (p3 - p1) * c.y;\r\n float t2 = t * t;\r\n float t3 = t * t * t;\r\n\r\n return vec3((2.0 * p1 - 2.0 * p2 + v0 + v1) * t3 + (-3.0 * p1 + 3.0 * p2 - 2.0 * v0 - v1) * t2 + v0 * t + p1);\r\n}\r\nvec3 catmullRomSpline(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t) {\r\n return catmullRomSpline(p0, p1, p2, p3, t, vec2(0.5, 0.5));\r\n}\r\n\r\nvec2 catmullRomSpline(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t, vec2 c) {\r\n vec2 v0 = (p2 - p0) * c.x;\r\n vec2 v1 = (p3 - p1) * c.y;\r\n float t2 = t * t;\r\n float t3 = t * t * t;\r\n\r\n return vec2((2.0 * p1 - 2.0 * p2 + v0 + v1) * t3 + (-3.0 * p1 + 3.0 * p2 - 2.0 * v0 - v1) * t2 + v0 * t + p1);\r\n}\r\nvec2 catmullRomSpline(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t) {\r\n return catmullRomSpline(p0, p1, p2, p3, t, vec2(0.5, 0.5));\r\n}\r\n\r\nfloat catmullRomSpline(float p0, float p1, float p2, float p3, float t, vec2 c) {\r\n float v0 = (p2 - p0) * c.x;\r\n float v1 = (p3 - p1) * c.y;\r\n float t2 = t * t;\r\n float t3 = t * t * t;\r\n\r\n return float((2.0 * p1 - 2.0 * p2 + v0 + v1) * t3 + (-3.0 * p1 + 3.0 * p2 - 2.0 * v0 - v1) * t2 + v0 * t + p1);\r\n}\r\nfloat catmullRomSpline(float p0, float p1, float p2, float p3, float t) {\r\n return catmullRomSpline(p0, p1, p2, p3, t, vec2(0.5, 0.5));\r\n}\r\n\r\nivec4 getCatmullRomSplineIndices(float l, float p) {\r\n float index = floor(p);\r\n int i0 = int(max(0.0, index - 1.0));\r\n int i1 = int(index);\r\n int i2 = int(min(index + 1.0, l));\r\n int i3 = int(min(index + 2.0, l));\r\n\r\n return ivec4(i0, i1, i2, i3);\r\n}\r\n\r\nivec4 getCatmullRomSplineIndicesClosed(float l, float p) {\r\n float index = floor(p);\r\n int i0 = int(index == 0.0 ? l : index - 1.0);\r\n int i1 = int(index);\r\n int i2 = int(mod(index + 1.0, l));\r\n int i3 = int(mod(index + 2.0, l));\r\n\r\n return ivec4(i0, i1, i2, i3);\r\n}\r\n";
var cubic_bezier = "vec3 cubicBezier(vec3 p0, vec3 c0, vec3 c1, vec3 p1, float t) {\r\n float tn = 1.0 - t;\r\n\r\n return tn * tn * tn * p0 + 3.0 * tn * tn * t * c0 + 3.0 * tn * t * t * c1 + t * t * t * p1;\r\n}\r\n\r\nvec2 cubicBezier(vec2 p0, vec2 c0, vec2 c1, vec2 p1, float t) {\r\n float tn = 1.0 - t;\r\n\r\n return tn * tn * tn * p0 + 3.0 * tn * tn * t * c0 + 3.0 * tn * t * t * c1 + t * t * t * p1;\r\n}\r\n";
var ease_back_in = "float easeBackIn(float p, float amplitude) {\r\n return p * p * ((amplitude + 1.0) * p - amplitude);\r\n}\r\n\r\nfloat easeBackIn(float p) {\r\n return easeBackIn(p, 1.70158);\r\n}\r\n\r\nfloat easeBackIn(float t, float b, float c, float d, float amplitude) {\r\n return b + easeBackIn(t / d, amplitude) * c;\r\n}\r\n\r\nfloat easeBackIn(float t, float b, float c, float d) {\r\n return b + easeBackIn(t / d) * c;\r\n}\r\n";
var ease_back_in_out = "float easeBackInOut(float p, float amplitude) {\r\n amplitude *= 1.525;\r\n\r\n return ((p *= 2.0) < 1.0) ? 0.5 * p * p * ((amplitude + 1.0) * p - amplitude) : 0.5 * ((p -= 2.0) * p * ((amplitude + 1.0) * p + amplitude) + 2.0);\r\n}\r\n\r\nfloat easeBackInOut(float p) {\r\n return easeBackInOut(p, 1.70158);\r\n}\r\n\r\nfloat easeBackInOut(float t, float b, float c, float d, float amplitude) {\r\n return b + easeBackInOut(t / d, amplitude) * c;\r\n}\r\n\r\nfloat easeBackInOut(float t, float b, float c, float d) {\r\n return b + easeBackInOut(t / d) * c;\r\n}\r\n";
var ease_back_out = "float easeBackOut(float p, float amplitude) {\r\n return ((p = p - 1.0) * p * ((amplitude + 1.0) * p + amplitude) + 1.0);\r\n}\r\n\r\nfloat easeBackOut(float p) {\r\n return easeBackOut(p, 1.70158);\r\n}\r\n\r\nfloat easeBackOut(float t, float b, float c, float d, float amplitude) {\r\n return b + easeBackOut(t / d, amplitude) * c;\r\n}\r\n\r\nfloat easeBackOut(float t, float b, float c, float d) {\r\n return b + easeBackOut(t / d) * c;\r\n}\r\n";
var ease_bezier = "float easeBezier(float p, vec4 curve) {\r\n float ip = 1.0 - p;\r\n return (3.0 * ip * ip * p * curve.xy + 3.0 * ip * p * p * curve.zw + p * p * p).y;\r\n}\r\n\r\nfloat easeBezier(float t, float b, float c, float d, vec4 curve) {\r\n return b + easeBezier(t / d, curve) * c;\r\n}\r\n";
var ease_bounce_in = "float easeBounceIn(float p) {\r\n if ((p = 1.0 - p) < 1.0 / 2.75) {\r\n return 1.0 - (7.5625 * p * p);\r\n } else if (p < 2.0 / 2.75) {\r\n return 1.0 - (7.5625 * (p -= 1.5 / 2.75) * p + 0.75);\r\n } else if (p < 2.5 / 2.75) {\r\n return 1.0 - (7.5625 * (p -= 2.25 / 2.75) * p + 0.9375);\r\n }\r\n return 1.0 - (7.5625 * (p -= 2.625 / 2.75) * p + 0.984375);\r\n}\r\n\r\nfloat easeBounceIn(float t, float b, float c, float d) {\r\n return b + easeBounceIn(t / d) * c;\r\n}\r\n";
var ease_bounce_in_out = "float easeBounceInOut(float p) {\r\n bool invert = (p < 0.5);\r\n\r\n p = invert ? (1.0 - (p * 2.0)) : ((p * 2.0) - 1.0);\r\n\r\n if (p < 1.0 / 2.75) {\r\n p = 7.5625 * p * p;\r\n } else if (p < 2.0 / 2.75) {\r\n p = 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;\r\n } else if (p < 2.5 / 2.75) {\r\n p = 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;\r\n } else {\r\n p = 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;\r\n }\r\n\r\n return invert ? (1.0 - p) * 0.5 : p * 0.5 + 0.5;\r\n}\r\n\r\nfloat easeBounceInOut(float t, float b, float c, float d) {\r\n return b + easeBounceInOut(t / d) * c;\r\n}\r\n";
var ease_bounce_out = "float easeBounceOut(float p) {\r\n if (p < 1.0 / 2.75) {\r\n return 7.5625 * p * p;\r\n } else if (p < 2.0 / 2.75) {\r\n return 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;\r\n } else if (p < 2.5 / 2.75) {\r\n return 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;\r\n }\r\n return 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;\r\n}\r\n\r\nfloat easeBounceOut(float t, float b, float c, float d) {\r\n return b + easeBounceOut(t / d) * c;\r\n}\r\n";
var ease_circ_in = "float easeCircIn(float p) {\r\n return -(sqrt(1.0 - p * p) - 1.0);\r\n}\r\n\r\nfloat easeCircIn(float t, float b, float c, float d) {\r\n return b + easeCircIn(t / d) * c;\r\n}\r\n";
var ease_circ_in_out = "float easeCircInOut(float p) {\r\n return ((p *= 2.0) < 1.0) ? -0.5 * (sqrt(1.0 - p * p) - 1.0) : 0.5 * (sqrt(1.0 - (p -= 2.0) * p) + 1.0);\r\n}\r\n\r\nfloat easeCircInOut(float t, float b, float c, float d) {\r\n return b + easeCircInOut(t / d) * c;\r\n}\r\n";
var ease_circ_out = "float easeCircOut(float p) {\r\n return sqrt(1.0 - (p = p - 1.0) * p);\r\n}\r\n\r\nfloat easeCircOut(float t, float b, float c, float d) {\r\n return b + easeCircOut(t / d) * c;\r\n}\r\n";
var ease_cubic_in = "float easeCubicIn(float t) {\r\n return t * t * t;\r\n}\r\n\r\nfloat easeCubicIn(float t, float b, float c, float d) {\r\n return b + easeCubicIn(t / d) * c;\r\n}\r\n";
var ease_cubic_in_out = "float easeCubicInOut(float t) {\r\n return (t /= 0.5) < 1.0 ? 0.5 * t * t * t : 0.5 * ((t-=2.0) * t * t + 2.0);\r\n}\r\n\r\nfloat easeCubicInOut(float t, float b, float c, float d) {\r\n return b + easeCubicInOut(t / d) * c;\r\n}\r\n";
var ease_cubic_out = "float easeCubicOut(float t) {\r\n float f = t - 1.0;\r\n return f * f * f + 1.0;\r\n}\r\n\r\nfloat easeCubicOut(float t, float b, float c, float d) {\r\n return b + easeCubicOut(t / d) * c;\r\n}\r\n";
var ease_elastic_in = "float easeElasticIn(float p, float amplitude, float period) {\r\n float p1 = max(amplitude, 1.0);\r\n float p2 = period / min(amplitude, 1.0);\r\n float p3 = p2 / PI2 * (asin(1.0 / p1));\r\n\r\n return -(p1 * pow(2.0, 10.0 * (p -= 1.0)) * sin((p - p3) * PI2 / p2));\r\n}\r\n\r\nfloat easeElasticIn(float p) {\r\n return easeElasticIn(p, 1.0, 0.3);\r\n}\r\n\r\nfloat easeElasticIn(float t, float b, float c, float d, float amplitude, float period) {\r\n return b + easeElasticIn(t / d, amplitude, period) * c;\r\n}\r\n\r\nfloat easeElasticIn(float t, float b, float c, float d) {\r\n return b + easeElasticIn(t / d) * c;\r\n}\r\n";
var ease_elastic_in_out = "float easeElasticInOut(float p, float amplitude, float period) {\r\n float p1 = max(amplitude, 1.0);\r\n float p2 = period / min(amplitude, 1.0);\r\n float p3 = p2 / PI2 * (asin(1.0 / p1));\r\n\r\n return ((p *= 2.0) < 1.0) ? -0.5 * (p1 * pow(2.0, 10.0 * (p -= 1.0)) * sin((p - p3) * PI2 / p2)) : p1 * pow(2.0, -10.0 * (p -= 1.0)) * sin((p - p3) * PI2 / p2) * 0.5 + 1.0;\r\n}\r\n\r\nfloat easeElasticInOut(float p) {\r\n return easeElasticInOut(p, 1.0, 0.3);\r\n}\r\n\r\nfloat easeElasticInOut(float t, float b, float c, float d, float amplitude, float period) {\r\n return b + easeElasticInOut(t / d, amplitude, period) * c;\r\n}\r\n\r\nfloat easeElasticInOut(float t, float b, float c, float d) {\r\n return b + easeElasticInOut(t / d) * c;\r\n}\r\n";
var ease_elastic_out = "float easeElasticOut(float p, float amplitude, float period) {\r\n float p1 = max(amplitude, 1.0);\r\n float p2 = period / min(amplitude, 1.0);\r\n float p3 = p2 / PI2 * (asin(1.0 / p1));\r\n\r\n return p1 * pow(2.0, -10.0 * p) * sin((p - p3) * PI2 / p2) + 1.0;\r\n}\r\n\r\nfloat easeElasticOut(float p) {\r\n return easeElasticOut(p, 1.0, 0.3);\r\n}\r\n\r\nfloat easeElasticOut(float t, float b, float c, float d, float amplitude, float period) {\r\n return b + easeElasticOut(t / d, amplitude, period) * c;\r\n}\r\n\r\nfloat easeElasticOut(float t, float b, float c, float d) {\r\n return b + easeElasticOut(t / d) * c;\r\n}\r\n";
var ease_expo_in = "float easeExpoIn(float p) {\r\n return pow(2.0, 10.0 * (p - 1.0));\r\n}\r\n\r\nfloat easeExpoIn(float t, float b, float c, float d) {\r\n return b + easeExpoIn(t / d) * c;\r\n}\r\n";
var ease_expo_in_out = "float easeExpoInOut(float p) {\r\n return ((p *= 2.0) < 1.0) ? 0.5 * pow(2.0, 10.0 * (p - 1.0)) : 0.5 * (2.0 - pow(2.0, -10.0 * (p - 1.0)));\r\n}\r\n\r\nfloat easeExpoInOut(float t, float b, float c, float d) {\r\n return b + easeExpoInOut(t / d) * c;\r\n}\r\n";
var ease_expo_out = "float easeExpoOut(float p) {\r\n return 1.0 - pow(2.0, -10.0 * p);\r\n}\r\n\r\nfloat easeExpoOut(float t, float b, float c, float d) {\r\n return b + easeExpoOut(t / d) * c;\r\n}\r\n";
var ease_quad_in = "float easeQuadIn(float t) {\r\n return t * t;\r\n}\r\n\r\nfloat easeQuadIn(float t, float b, float c, float d) {\r\n return b + easeQuadIn(t / d) * c;\r\n}\r\n";
var ease_quad_in_out = "float easeQuadInOut(float t) {\r\n float p = 2.0 * t * t;\r\n return t < 0.5 ? p : -p + (4.0 * t) - 1.0;\r\n}\r\n\r\nfloat easeQuadInOut(float t, float b, float c, float d) {\r\n return b + easeQuadInOut(t / d) * c;\r\n}\r\n";
var ease_quad_out = "float easeQuadOut(float t) {\r\n return -t * (t - 2.0);\r\n}\r\n\r\nfloat easeQuadOut(float t, float b, float c, float d) {\r\n return b + easeQuadOut(t / d) * c;\r\n}\r\n";
var ease_quart_in = "float easeQuartIn(float t) {\r\n return t * t * t * t;\r\n}\r\n\r\nfloat easeQuartIn(float t, float b, float c, float d) {\r\n return b + easeQuartIn(t / d) * c;\r\n}\r\n";
var ease_quart_in_out = "float easeQuartInOut(float t) {\r\n return t < 0.5 ? 8.0 * pow(t, 4.0) : -8.0 * pow(t - 1.0, 4.0) + 1.0;\r\n}\r\n\r\nfloat easeQuartInOut(float t, float b, float c, float d) {\r\n return b + easeQuartInOut(t / d) * c;\r\n}\r\n";
var ease_quart_out = "float easeQuartOut(float t) {\r\n return 1.0 - pow(1.0 - t, 4.0);\r\n}\r\n\r\nfloat easeQuartOut(float t, float b, float c, float d) {\r\n return b + easeQuartOut(t / d) * c;\r\n}\r\n";
var ease_quint_in = "float easeQuintIn(float t) {\r\n return pow(t, 5.0);\r\n}\r\n\r\nfloat easeQuintIn(float t, float b, float c, float d) {\r\n return b + easeQuintIn(t / d) * c;\r\n}\r\n";
var ease_quint_in_out = "float easeQuintInOut(float t) {\r\n return (t /= 0.5) < 1.0 ? 0.5 * t * t * t * t * t : 0.5 * ((t -= 2.0) * t * t * t * t + 2.0);\r\n}\r\n\r\nfloat easeQuintInOut(float t, float b, float c, float d) {\r\n return b + easeQuintInOut(t / d) * c;\r\n}\r\n";
var ease_quint_out = "float easeQuintOut(float t) {\r\n return (t -= 1.0) * t * t * t * t + 1.0;\r\n}\r\n\r\nfloat easeQuintOut(float t, float b, float c, float d) {\r\n return b + easeQuintOut(t / d) * c;\r\n}\r\n";
var ease_sine_in = "float easeSineIn(float p) {\r\n return -cos(p * 1.57079632679) + 1.0;\r\n}\r\n\r\nfloat easeSineIn(float t, float b, float c, float d) {\r\n return b + easeSineIn(t / d) * c;\r\n}\r\n";
var ease_sine_in_out = "float easeSineInOut(float p) {\r\n return -0.5 * (cos(PI * p) - 1.0);\r\n}\r\n\r\nfloat easeSineInOut(float t, float b, float c, float d) {\r\n return b + easeSineInOut(t / d) * c;\r\n}\r\n";
var ease_sine_out = "float easeSineOut(float p) {\r\n return sin(p * 1.57079632679);\r\n}\r\n\r\nfloat easeSineOut(float t, float b, float c, float d) {\r\n return b + easeSineOut(t / d) * c;\r\n}\r\n";
var quadratic_bezier = "vec3 quadraticBezier(vec3 p0, vec3 c0, vec3 p1, float t) {\r\n float tn = 1.0 - t;\r\n\r\n return tn * tn * p0 + 2.0 * tn * t * c0 + t * t * p1;\r\n}\r\n\r\nvec2 quadraticBezier(vec2 p0, vec2 c0, vec2 p1, float t) {\r\n float tn = 1.0 - t;\r\n\r\n return tn * tn * p0 + 2.0 * tn * t * c0 + t * t * p1;\r\n}";
var quaternion_rotation = "vec3 rotateVector(vec4 q, vec3 v) {\r\n return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\r\n}\r\n\r\nvec4 quatFromAxisAngle(vec3 axis, float angle) {\r\n float halfAngle = angle * 0.5;\r\n return vec4(axis.xyz * sin(halfAngle), cos(halfAngle));\r\n}\r\n";
var quaternion_slerp = "vec4 quatSlerp(vec4 q0, vec4 q1, float t) {\r\n float s = 1.0 - t;\r\n float c = dot(q0, q1);\r\n float dir = -1.0; //c >= 0.0 ? 1.0 : -1.0;\r\n float sqrSn = 1.0 - c * c;\r\n\r\n if (sqrSn > 2.220446049250313e-16) {\r\n float sn = sqrt(sqrSn);\r\n float len = atan(sn, c * dir);\r\n\r\n s = sin(s * len) / sn;\r\n t = sin(t * len) / sn;\r\n }\r\n\r\n float tDir = t * dir;\r\n\r\n return normalize(q0 * s + q1 * tDir);\r\n}\r\n";
// generated by scripts/build_shader_chunks.js
var ShaderChunk = {
catmull_rom_spline: catmull_rom_spline,
cubic_bezier: cubic_bezier,
ease_back_in: ease_back_in,
ease_back_in_out: ease_back_in_out,
ease_back_out: ease_back_out,
ease_bezier: ease_bezier,
ease_bounce_in: ease_bounce_in,
ease_bounce_in_out: ease_bounce_in_out,
ease_bounce_out: ease_bounce_out,
ease_circ_in: ease_circ_in,
ease_circ_in_out: ease_circ_in_out,
ease_circ_out: ease_circ_out,
ease_cubic_in: ease_cubic_in,
ease_cubic_in_out: ease_cubic_in_out,
ease_cubic_out: ease_cubic_out,
ease_elastic_in: ease_elastic_in,
ease_elastic_in_out: ease_elastic_in_out,
ease_elastic_out: ease_elastic_out,
ease_expo_in: ease_expo_in,
ease_expo_in_out: ease_expo_in_out,
ease_expo_out: ease_expo_out,
ease_quad_in: ease_quad_in,
ease_quad_in_out: ease_quad_in_out,
ease_quad_out: ease_quad_out,
ease_quart_in: ease_quart_in,
ease_quart_in_out: ease_quart_in_out,
ease_quart_out: ease_quart_out,
ease_quint_in: ease_quint_in,
ease_quint_in_out: ease_quint_in_out,
ease_quint_out: ease_quint_out,
ease_sine_in: ease_sine_in,
ease_sine_in_out: ease_sine_in_out,
ease_sine_out: ease_sine_out,
quadratic_bezier: quadratic_bezier,
quaternion_rotation: quaternion_rotation,
quaternion_slerp: quaternion_slerp
};
/**
* A timeline transition segment. An instance of this class is created internally when calling {@link THREE.BAS.Timeline.add}, so you should not use this class directly.
* The instance is also passed the the compiler function if you register a transition through {@link THREE.BAS.Timeline.register}. There you can use the public properties of the segment to compile the glsl string.
* @param {string} key A string key generated by the timeline to which this segment belongs. Keys are unique.
* @param {number} start Start time of this segment in a timeline in seconds.
* @param {number} duration Duration of this segment in seconds.
* @param {object} transition Object describing the transition.
* @param {function} compiler A reference to the compiler function from a transition definition.
* @constructor
*/
function TimelineSegment(key, start, duration, transition, compiler) {
this.key = key;
this.start = start;
this.duration = duration;
this.transition = transition;
this.compiler = compiler;
this.trail = 0;
}
TimelineSegment.prototype.compile = function () {
return this.compiler(this);
};
Object.defineProperty(TimelineSegment.prototype, 'end', {
get: function get() {
return this.start + this.duration;
}
});
/**
* A utility class to create an animation timeline which can be baked into a (vertex) shader.
* By default the timeline supports translation, scale and rotation. This can be extended or overridden.
* @constructor
*/
function Timeline() {
/**
* The total duration of the timeline in seconds.
* @type {number}
*/
this.duration = 0;
/**
* The name of the value that segments will use to read the time. Defaults to 'tTime'.
* @type {string}
*/
this.timeKey = 'tTime';
this.segments = {};
this.__key = 0;
}
// static definitions map
Timeline.segmentDefinitions = {};
/**
* Registers a transition definition for use with {@link THREE.BAS.Timeline.add}.
* @param {String} key Name of the transition. Defaults include 'scale', 'rotate' and 'translate'.
* @param {Object} definition
* @param {Function} definition.compiler A function that generates a glsl string for a transition segment. Accepts a THREE.BAS.TimelineSegment as the sole argument.
* @param {*} definition.defaultFrom The initial value for a transform.from. For example, the defaultFrom for a translation is THREE.Vector3(0, 0, 0).
* @static
*/
Timeline.register = function (key, definition) {
Timeline.segmentDefinitions[key] = definition;
return definition;
};
/**
* Add a transition to the timeline.
* @param {number} duration Duration in seconds
* @param {object} transitions An object containing one or several transitions. The keys should match transform definitions.
* The transition object for each key will be passed to the matching definition's compiler. It can have arbitrary properties, but the Timeline expects at least a 'to', 'from' and an optional 'ease'.
* @param {number|string} [positionOffset] Position in the timeline. Defaults to the end of the timeline. If a number is provided, the transition will be inserted at that time in seconds. Strings ('+=x' or '-=x') can be used for a value relative to the end of timeline.
*/
Timeline.prototype.add = function (duration, transitions, positionOffset) {
// stop rollup from complaining about eval
var _eval = eval;
var start = this.duration;
if (positionOffset !== undefined) {
if (typeof positionOffset === 'number') {
start = positionOffset;
} else if (typeof positionOffset === 'string') {
_eval('start' + positionOffset);
}
this.duration = Math.max(this.duration, start + duration);
} else {
this.duration += duration;
}
var keys = Object.keys(transitions),
key = void 0;
for (var i = 0; i < keys.length; i++) {
key = keys[i];
this.processTransition(key, transitions[key], start, duration);
}
};
Timeline.prototype.processTransition = function (key, transition, start, duration) {
var definition = Timeline.segmentDefinitions[key];
var segments = this.segments[key];
if (!segments) segments = this.segments[key] = [];
if (transition.from === undefined) {
if (segments.length === 0) {
transition.from = definition.defaultFrom;
} else {
transition.from = segments[segments.length - 1].transition.to;
}
}
segments.push(new TimelineSegment((this.__key++).toString(), start, duration, transition, definition.compiler));
};
/**
* Compiles the timeline into a glsl string array that can be injected into a (vertex) shader.
* @returns {Array}
*/
Timeline.prototype.compile = function () {
var c = [];
var keys = Object.keys(this.segments);
var segments = void 0;
for (var i = 0; i < keys.length; i++) {
segments = this.segments[keys[i]];
this.fillGaps(segments);
segments.forEach(function (s) {
c.push(s.compile());
});
}
return c;
};
Timeline.prototype.fillGaps = function (segments) {
if (segments.length === 0) return;
var s0 = void 0,
s1 = void 0;
for (var i = 0; i < segments.length - 1; i++) {
s0 = segments[i];
s1 = segments[i + 1];
s0.trail = s1.start - s0.end;
}
// pad last segment until end of timeline
s0 = segments[segments.length - 1];
s0.trail = this.duration - s0.end;
};
/**
* Get a compiled glsl string with calls to transform functions for a given key.
* The order in which these transitions are applied matters because they all operate on the same value.
* @param {string} key A key matching a transform definition.
* @returns {string}
*/
Timeline.prototype.getTransformCalls = function (key) {
var t = this.timeKey;
return this.segments[key] ? this.segments[key].map(function (s) {
return 'applyTransform' + s.key + '(' + t + ', transformed);';
}).join('\n') : '';
};
var TimelineChunks = {
vec3: function vec3(n, v, p) {
var x = (v.x || 0).toPrecision(p);
var y = (v.y || 0).toPrecision(p);
var z = (v.z || 0).toPrecision(p);
return "vec3 " + n + " = vec3(" + x + ", " + y + ", " + z + ");";
},
vec4: function vec4(n, v, p) {
var x = (v.x || 0).toPrecision(p);
var y = (v.y || 0).toPrecision(p);
var z = (v.z || 0).toPrecision(p);
var w = (v.w || 0).toPrecision(p);
return "vec4 " + n + " = vec4(" + x + ", " + y + ", " + z + ", " + w + ");";
},
delayDuration: function delayDuration(segment) {
return "\n float cDelay" + segment.key + " = " + segment.start.toPrecision(4) + ";\n float cDuration" + segment.key + " = " + segment.duration.toPrecision(4) + ";\n ";
},
progress: function progress(segment) {
// zero duration segments should always render complete
if (segment.duration === 0) {
return "float progress = 1.0;";
} else {
return "\n float progress = clamp(time - cDelay" + segment.key + ", 0.0, cDuration" + segment.key + ") / cDuration" + segment.key + ";\n " + (segment.transition.ease ? "progress = " + segment.transition.ease + "(progress" + (segment.transition.easeParams ? ", " + segment.transition.easeParams.map(function (v) {
return v.toPrecision(4);
}).join(", ") : "") + ");" : "") + "\n ";
}
},
renderCheck: function renderCheck(segment) {
var startTime = segment.start.toPrecision(4);
var endTime = (segment.end + segment.trail).toPrecision(4);
return "if (time < " + startTime + " || time > " + endTime + ") return;";
}
};
var TranslationSegment = {
compiler: function compiler(segment) {
return '\n ' + TimelineChunks.delayDuration(segment) + '\n ' + TimelineChunks.vec3('cTranslateFrom' + segment.key, segment.transition.from, 2) + '\n ' + TimelineChunks.vec3('cTranslateTo' + segment.key, segment.transition.to, 2) + '\n \n void applyTransform' + segment.key + '(float time, inout vec3 v) {\n \n ' + TimelineChunks.renderCheck(segment) + '\n ' + TimelineChunks.progress(segment) + '\n \n v += mix(cTranslateFrom' + segment.key + ', cTranslateTo' + segment.key + ', progress);\n }\n ';
},
defaultFrom: new three.Vector3(0, 0, 0)
};
Timeline.register('translate', TranslationSegment);
var ScaleSegment = {
compiler: function compiler(segment) {
var origin = segment.transition.origin;
return '\n ' + TimelineChunks.delayDuration(segment) + '\n ' + TimelineChunks.vec3('cScaleFrom' + segment.key, segment.transition.from, 2) + '\n ' + TimelineChunks.vec3('cScaleTo' + segment.key, segment.transition.to, 2) + '\n ' + (origin ? TimelineChunks.vec3('cOrigin' + segment.key, origin, 2) : '') + '\n \n void applyTransform' + segment.key + '(float time, inout vec3 v) {\n \n ' + TimelineChunks.renderCheck(segment) + '\n ' + TimelineChunks.progress(segment) + '\n \n ' + (origin ? 'v -= cOrigin' + segment.key + ';' : '') + '\n v *= mix(cScaleFrom' + segment.key + ', cScaleTo' + segment.key + ', progress);\n ' + (origin ? 'v += cOrigin' + segment.key + ';' : '') + '\n }\n ';
},
defaultFrom: new three.Vector3(1, 1, 1)
};
Timeline.register('scale', ScaleSegment);
var RotationSegment = {
compiler: function compiler(segment) {
var fromAxisAngle = new three.Vector4(segment.transition.from.axis.x, segment.transition.from.axis.y, segment.transition.from.axis.z, segment.transition.from.angle);
var toAxis = segment.transition.to.axis || segment.transition.from.axis;
var toAxisAngle = new three.Vector4(toAxis.x, toAxis.y, toAxis.z, segment.transition.to.angle);
var origin = segment.transition.origin;
return '\n ' + TimelineChunks.delayDuration(segment) + '\n ' + TimelineChunks.vec4('cRotationFrom' + segment.key, fromAxisAngle, 8) + '\n ' + TimelineChunks.vec4('cRotationTo' + segment.key, toAxisAngle, 8) + '\n ' + (origin ? TimelineChunks.vec3('cOrigin' + segment.key, origin, 2) : '') + '\n \n void applyTransform' + segment.key + '(float time, inout vec3 v) {\n ' + TimelineChunks.renderCheck(segment) + '\n ' + TimelineChunks.progress(segment) + '\n\n ' + (origin ? 'v -= cOrigin' + segment.key + ';' : '') + '\n vec3 axis = normalize(mix(cRotationFrom' + segment.key + '.xyz, cRotationTo' + segment.key + '.xyz, progress));\n float angle = mix(cRotationFrom' + segment.key + '.w, cRotationTo' + segment.key + '.w, progress);\n vec4 q = quatFromAxisAngle(axis, angle);\n v = rotateVector(q, v);\n ' + (origin ? 'v += cOrigin' + segment.key + ';' : '') + '\n }\n ';
},
defaultFrom: { axis: new three.Vector3(), angle: 0 }
};
Timeline.register('rotate', RotationSegment);
exports.BasicAnimationMaterial = BasicAnimationMaterial;
exports.LambertAnimationMaterial = LambertAnimationMaterial;
exports.PhongAnimationMaterial = PhongAnimationMaterial;
exports.StandardAnimationMaterial = StandardAnimationMaterial;
exports.PointsAnimationMaterial = PointsAnimationMaterial;
exports.DepthAnimationMaterial = DepthAnimationMaterial;
exports.DistanceAnimationMaterial = DistanceAnimationMaterial;
exports.PrefabBufferGeometry = PrefabBufferGeometry;
exports.MultiPrefabBufferGeometry = MultiPrefabBufferGeometry;
exports.ModelBufferGeometry = ModelBufferGeometry;
exports.PointBufferGeometry = PointBufferGeometry;
exports.ShaderChunk = ShaderChunk;
exports.Timeline = Timeline;
exports.TimelineSegment = TimelineSegment;
exports.TimelineChunks = TimelineChunks;
exports.TranslationSegment = TranslationSegment;
exports.ScaleSegment = ScaleSegment;
exports.RotationSegment = RotationSegment;
exports.Utils = Utils;
Object.defineProperty(exports, '__esModule', { value: true });
})));