icn3d 3.44.2 → 3.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/icn3d.js CHANGED
@@ -36340,7 +36340,7 @@ var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor
36340
36340
 
36341
36341
  var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong";
36342
36342
 
36343
- var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 fdx = dFdx( vViewPosition );\nvec3 fdy = dFdy( vViewPosition );\nvec3 nonPerturbedNormal = normalize( cross( fdx, fdy ) );\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif";
36343
+ var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nfloat geometryRoughness = 0.0;\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif";
36344
36344
 
36345
36345
  var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\tfloat dispersion;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat anisotropy;\n\t\tfloat alphaT;\n\t\tvec3 anisotropyT;\n\t\tvec3 anisotropyB;\n\t#endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_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}\n#ifdef USE_ANISOTROPY\n\tfloat V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n\t\tfloat gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n\t\tfloat gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n\t\tfloat v = 0.5 / ( gv + gl );\n\t\treturn saturate(v);\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.specularColor;\n\tfloat f90 = material.specularF90;\n\tfloat roughness = material.roughness;\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t#ifdef USE_IRIDESCENCE\n\t\tF = mix( F, material.iridescenceFresnel, material.iridescence );\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat dotTL = dot( material.anisotropyT, lightDir );\n\t\tfloat dotTV = dot( material.anisotropyT, viewDir );\n\t\tfloat dotTH = dot( material.anisotropyT, halfDir );\n\t\tfloat dotBL = dot( material.anisotropyB, lightDir );\n\t\tfloat dotBV = dot( material.anisotropyB, viewDir );\n\t\tfloat dotBH = dot( material.anisotropyB, halfDir );\n\t\tfloat V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n\t\tfloat D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n\t#else\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t#endif\n\treturn F * ( V * 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}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometryNormal;\n\t\tvec3 viewDir = geometryViewDir;\n\t\tvec3 position = geometryPosition;\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.roughness;\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 vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += radiance * singleScattering;\n\treflectedLight.indirectSpecular += 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}";
36346
36346
 
@@ -55114,7 +55114,7 @@ class MyEventCls {
55114
55114
  }
55115
55115
 
55116
55116
  onId(id, eventName, myFunction) { this.icn3dui;
55117
- if(Object.keys(window).length < 2) return;
55117
+ if(Object.keys(window).length < 3) return;
55118
55118
 
55119
55119
  if(id.substr(0, 1) == '#') id = id.substr(1);
55120
55120
  if(document.getElementById(id)) {
@@ -74147,13 +74147,18 @@ class Scene {
74147
74147
  rebuildScene(options) { let ic = this.icn3d, me = ic.icn3dui;
74148
74148
  if(options === undefined) options = ic.opts;
74149
74149
 
74150
+ // whether camera was set
74151
+ me.bCamera = (ic.cam) ? true : false;
74152
+
74150
74153
  this.rebuildSceneBase(options);
74151
74154
 
74152
74155
  ic.fogCls.setFog();
74153
74156
 
74154
- // if(!ic.bVr && !ic.bAr) { // first time
74157
+ if(ic.bSetCamera) { // load a URL with trackball transformation, or no info after "|||"
74155
74158
  ic.cameraCls.setCamera();
74156
- // }
74159
+ }
74160
+
74161
+ if(ic.opts['slab'] === 'yes') ic.cameraCls.setSlab();
74157
74162
 
74158
74163
  // if(!ic.bSetVrArButtons) { // call once
74159
74164
  if(!me.cfg.imageonly) this.setVrArButtons();
@@ -75353,7 +75358,7 @@ function TrackballControls( object, domElement, icn3d ) {
75353
75358
  function keydown( event ) {
75354
75359
  //console.log("keydown");
75355
75360
 
75356
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75361
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75357
75362
 
75358
75363
  window.removeEventListener( 'keydown', keydown );
75359
75364
 
@@ -75384,7 +75389,7 @@ function TrackballControls( object, domElement, icn3d ) {
75384
75389
  function keyup( event ) {
75385
75390
  //console.log("keyup");
75386
75391
 
75387
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75392
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75388
75393
 
75389
75394
  _this._state = _prevState;
75390
75395
 
@@ -75394,7 +75399,7 @@ function TrackballControls( object, domElement, icn3d ) {
75394
75399
 
75395
75400
  function mousedown( event ) {
75396
75401
 
75397
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75402
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75398
75403
 
75399
75404
  //event.preventDefault();
75400
75405
  event.stopPropagation();
@@ -75431,7 +75436,7 @@ function TrackballControls( object, domElement, icn3d ) {
75431
75436
 
75432
75437
  function mousemove( event ) {
75433
75438
 
75434
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75439
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75435
75440
 
75436
75441
  //event.preventDefault();
75437
75442
  event.stopPropagation();
@@ -75454,7 +75459,7 @@ function TrackballControls( object, domElement, icn3d ) {
75454
75459
  }
75455
75460
 
75456
75461
  function mouseup( event ) {
75457
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75462
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75458
75463
 
75459
75464
  //event.preventDefault();
75460
75465
  event.stopPropagation();
@@ -75469,7 +75474,7 @@ function TrackballControls( object, domElement, icn3d ) {
75469
75474
 
75470
75475
  function mousewheel( event ) {
75471
75476
 
75472
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75477
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75473
75478
 
75474
75479
  //event.preventDefault();
75475
75480
  event.stopPropagation();
@@ -75496,7 +75501,7 @@ function TrackballControls( object, domElement, icn3d ) {
75496
75501
 
75497
75502
  function touchstart( event ) {
75498
75503
 
75499
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75504
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75500
75505
 
75501
75506
  switch ( event.touches.length ) {
75502
75507
  case 1:
@@ -75528,7 +75533,7 @@ function TrackballControls( object, domElement, icn3d ) {
75528
75533
 
75529
75534
  function touchmove( event ) {
75530
75535
 
75531
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75536
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75532
75537
 
75533
75538
  //event.preventDefault();
75534
75539
  event.stopPropagation();
@@ -75558,7 +75563,7 @@ function TrackballControls( object, domElement, icn3d ) {
75558
75563
 
75559
75564
  function touchend( event ) {
75560
75565
 
75561
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
75566
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
75562
75567
 
75563
75568
  switch ( event.touches.length ) {
75564
75569
 
@@ -75583,7 +75588,7 @@ function TrackballControls( object, domElement, icn3d ) {
75583
75588
 
75584
75589
  }
75585
75590
 
75586
- if(Object.keys(window).length >= 2 && this.domElement) {
75591
+ if(Object.keys(window).length >= 3 && this.domElement) {
75587
75592
  this.domElement.addEventListener( 'contextmn', function ( event ) {
75588
75593
  //event.preventDefault();
75589
75594
  }, false );
@@ -75597,8 +75602,8 @@ function TrackballControls( object, domElement, icn3d ) {
75597
75602
  this.domElement.addEventListener( 'touchend', touchend, false );
75598
75603
  this.domElement.addEventListener( 'touchmove', touchmove, false );
75599
75604
 
75600
- if(Object.keys(window).length >= 2) window.addEventListener( 'keydown', keydown, false );
75601
- if(Object.keys(window).length >= 2) window.addEventListener( 'keyup', keyup, false );
75605
+ if(Object.keys(window).length >= 3) window.addEventListener( 'keydown', keydown, false );
75606
+ if(Object.keys(window).length >= 3) window.addEventListener( 'keyup', keyup, false );
75602
75607
  }
75603
75608
 
75604
75609
  this.handleResize();
@@ -76031,7 +76036,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76031
76036
 
76032
76037
  function keydown( event ) {
76033
76038
 
76034
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76039
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76035
76040
 
76036
76041
  window.removeEventListener( 'keydown', keydown );
76037
76042
 
@@ -76059,7 +76064,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76059
76064
 
76060
76065
  function keyup( event ) {
76061
76066
 
76062
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76067
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76063
76068
 
76064
76069
  _this._state = _prevState;
76065
76070
 
@@ -76069,7 +76074,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76069
76074
 
76070
76075
  function mousedown( event ) {
76071
76076
 
76072
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76077
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76073
76078
 
76074
76079
  //event.preventDefault();
76075
76080
  event.stopPropagation();
@@ -76106,7 +76111,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76106
76111
 
76107
76112
  function mousemove( event ) {
76108
76113
 
76109
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76114
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76110
76115
 
76111
76116
  //event.preventDefault();
76112
76117
  event.stopPropagation();
@@ -76129,7 +76134,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76129
76134
 
76130
76135
  function mouseup( event ) {
76131
76136
 
76132
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76137
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76133
76138
 
76134
76139
  //event.preventDefault();
76135
76140
  event.stopPropagation();
@@ -76144,7 +76149,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76144
76149
 
76145
76150
  function mousewheel( event ) {
76146
76151
 
76147
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76152
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76148
76153
 
76149
76154
  //event.preventDefault();
76150
76155
  event.stopPropagation();
@@ -76170,7 +76175,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76170
76175
 
76171
76176
  function touchstart( event ) {
76172
76177
 
76173
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76178
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76174
76179
 
76175
76180
  switch ( event.touches.length ) {
76176
76181
 
@@ -76203,7 +76208,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76203
76208
 
76204
76209
  function touchmove( event ) {
76205
76210
 
76206
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76211
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76207
76212
 
76208
76213
  //event.preventDefault();
76209
76214
  event.stopPropagation();
@@ -76233,7 +76238,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76233
76238
 
76234
76239
  function touchend( event ) {
76235
76240
 
76236
- if ( _this.enabled === false || Object.keys(window).length < 2) return;
76241
+ if ( _this.enabled === false || Object.keys(window).length < 3) return;
76237
76242
 
76238
76243
  switch ( event.touches.length ) {
76239
76244
 
@@ -76258,7 +76263,7 @@ function OrthographicTrackballControls( object, domElement, icn3d ) { var me = t
76258
76263
 
76259
76264
  }
76260
76265
 
76261
- if(Object.keys(window).length >= 2 && this.domElement) {
76266
+ if(Object.keys(window).length >= 3 && this.domElement) {
76262
76267
  this.domElement.addEventListener( 'contextmn', function ( event ) {
76263
76268
  //event.preventDefault();
76264
76269
  }, false );
@@ -76304,7 +76309,8 @@ class Camera {
76304
76309
 
76305
76310
  let maxD = ic.maxD;
76306
76311
 
76307
- if(window.cam === ic.perspectiveCamera) {
76312
+ // if(window.cam === ic.perspectiveCamera) {
76313
+ if(ic.opts.camera.toLowerCase() == 'perspective') {
76308
76314
  let bInstance = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > ic.maxatomcnt) ? true : false;
76309
76315
  //var factor = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > 10 * ic.maxatomcnt) ? 1 : 2;
76310
76316
  //var factor = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > 10 * ic.maxatomcnt) ? 1 : 3;
@@ -76319,26 +76325,26 @@ class Camera {
76319
76325
  }
76320
76326
 
76321
76327
  if(window.cam_z > 0) {
76322
- window.cam.position.z = maxD * window.camMaxDFactor; // for perspective, the z position should be large enough to see the whole molecule
76328
+ window.cam.position.z = maxD * window.camMaxDFactor; // for perspective, the z position should be large enough to see the whole molecule
76323
76329
  }
76324
76330
  else {
76325
- window.cam.position.z = -maxD * window.camMaxDFactor; // for perspective, the z position should be large enough to see the whole molecule
76331
+ window.cam.position.z = -maxD * window.camMaxDFactor; // for perspective, the z position should be large enough to see the whole molecule
76326
76332
  }
76327
76333
 
76328
- if(ic.opts['slab'] === 'yes') {
76329
- if(bInstance) {
76330
- window.cam.near = 0.1;
76331
- }
76332
- else if(window.camMaxDFactorFog !== undefined) {
76333
- window.cam.near = maxD * window.camMaxDFactorFog - 10; // keep some surrounding residues
76334
- }
76335
- else {
76336
- window.cam.near = maxD * window.camMaxDFactor;
76337
- }
76338
- }
76339
- else {
76334
+ // if(ic.opts['slab'] === 'yes') {
76335
+ // if(bInstance) {
76336
+ // window.cam.near = 0.1;
76337
+ // }
76338
+ // else if(window.camMaxDFactorFog !== undefined) {
76339
+ // window.cam.near = maxD * window.camMaxDFactorFog - 10; // keep some surrounding residues
76340
+ // }
76341
+ // else {
76342
+ // window.cam.near = maxD * window.camMaxDFactor;
76343
+ // }
76344
+ // }
76345
+ // else {
76340
76346
  window.cam.near = 0.1;
76341
- }
76347
+ // }
76342
76348
  window.cam.far = 10000;
76343
76349
 
76344
76350
  if(ic.bControlGl && !me.bNode) {
@@ -76353,7 +76359,8 @@ class Camera {
76353
76359
  }
76354
76360
  }
76355
76361
  }
76356
- else if (window.cam === ic.orthographicCamera){
76362
+ // else if (window.cam === ic.orthographicCamera){
76363
+ else if(ic.opts.camera.toLowerCase() == 'orthographic') {
76357
76364
  if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > 10 * ic.maxatomcnt) {
76358
76365
  window.cam.right = ic.maxD/2 * 1.5;
76359
76366
  }
@@ -76365,12 +76372,12 @@ class Camera {
76365
76372
  window.cam.top = window.cam.right /ic.container.whratio;
76366
76373
  window.cam.bottom = -window.cam.right /ic.container.whratio;
76367
76374
 
76368
- if(ic.opts['slab'] === 'yes') {
76369
- window.cam.near = ic.maxD * 2;
76370
- }
76371
- else {
76375
+ // if(ic.opts['slab'] === 'yes') {
76376
+ // window.cam.near = ic.maxD * 2;
76377
+ // }
76378
+ // else {
76372
76379
  window.cam.near = 0;
76373
- }
76380
+ // }
76374
76381
 
76375
76382
  window.cam.far = 10000;
76376
76383
 
@@ -76396,7 +76403,8 @@ class Camera {
76396
76403
 
76397
76404
  let maxD = ic.maxD;
76398
76405
 
76399
- if(ic.cam === ic.perspectiveCamera) {
76406
+ // if(ic.cam === ic.perspectiveCamera) {
76407
+ if(ic.opts.camera.toLowerCase() == 'perspective') {
76400
76408
  let bInstance = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > ic.maxatomcnt) ? true : false;
76401
76409
  //var factor = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > 10 * ic.maxatomcnt) ? 1 : 2;
76402
76410
  //var factor = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > 10 * ic.maxatomcnt) ? 1 : 3;
@@ -76411,26 +76419,26 @@ class Camera {
76411
76419
  }
76412
76420
 
76413
76421
  if(ic.cam_z > 0) {
76414
- ic.cam.position.z = maxD * ic.camMaxDFactor; // forperspective, the z positionshould be large enough to see the whole molecule
76422
+ ic.cam.position.z = maxD * ic.camMaxDFactor; // forperspective, the z positionshould be large enough to see the whole molecule
76415
76423
  }
76416
76424
  else {
76417
- ic.cam.position.z = -maxD * ic.camMaxDFactor; // forperspective, the z positionshould be large enough to see the whole molecule
76425
+ ic.cam.position.z = -maxD * ic.camMaxDFactor; // forperspective, the z positionshould be large enough to see the whole molecule
76418
76426
  }
76419
76427
 
76420
- if(ic.opts['slab'] === 'yes') {
76421
- if(bInstance) {
76422
- ic.cam.near = 0.1;
76423
- }
76424
- else if(ic.camMaxDFactorFog !== undefined) {
76425
- ic.cam.near = maxD * ic.camMaxDFactorFog - 10; // keep some surrounding residues
76426
- }
76427
- else {
76428
- ic.cam.near = maxD * ic.camMaxDFactor;
76429
- }
76430
- }
76431
- else {
76428
+ // if(ic.opts['slab'] === 'yes') {
76429
+ // if(bInstance) {
76430
+ // ic.cam.near = 0.1;
76431
+ // }
76432
+ // else if(ic.camMaxDFactorFog !== undefined) {
76433
+ // ic.cam.near = maxD * ic.camMaxDFactorFog - 10; // keep some surrounding residues
76434
+ // }
76435
+ // else {
76436
+ // ic.cam.near = maxD * ic.camMaxDFactor;
76437
+ // }
76438
+ // }
76439
+ // else {
76432
76440
  ic.cam.near = 0.1;
76433
- }
76441
+ // }
76434
76442
  ic.cam.far = 10000;
76435
76443
 
76436
76444
  if(ic.bControlGl && !me.bNode) {
@@ -76445,7 +76453,8 @@ class Camera {
76445
76453
  }
76446
76454
  }
76447
76455
  }
76448
- else if (ic.cam === ic.orthographicCamera){
76456
+ // else if (ic.cam === ic.orthographicCamera){
76457
+ else if(ic.opts.camera.toLowerCase() == 'orthographic') {
76449
76458
  if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > 10 * ic.maxatomcnt) {
76450
76459
  ic.cam.right = ic.maxD/2 * 1.5;
76451
76460
  }
@@ -76457,12 +76466,12 @@ class Camera {
76457
76466
  ic.cam.top = ic.cam.right /ic.container.whratio;
76458
76467
  ic.cam.bottom = -ic.cam.right /ic.container.whratio;
76459
76468
 
76460
- if(ic.opts['slab'] === 'yes') {
76461
- ic.cam.near = ic.maxD * 2;
76462
- }
76463
- else {
76469
+ // if(ic.opts['slab'] === 'yes') {
76470
+ // ic.cam.near = ic.maxD * 2;
76471
+ // }
76472
+ // else {
76464
76473
  ic.cam.near = 0;
76465
- }
76474
+ // }
76466
76475
 
76467
76476
  ic.cam.far = 10000;
76468
76477
 
@@ -76484,6 +76493,85 @@ class Camera {
76484
76493
  ic.cam.updateProjectionMatrix();
76485
76494
  // }
76486
76495
  }
76496
+
76497
+ setSlab() { let ic = this.icn3d, me = ic.icn3dui;
76498
+ if(ic.bControlGl && !me.bNode) {
76499
+ let maxD = ic.maxD;
76500
+
76501
+ // if(window.cam === ic.perspectiveCamera) {
76502
+ if(ic.opts.camera.toLowerCase() == 'perspective') {
76503
+ let bInstance = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > ic.maxatomcnt) ? true : false;
76504
+
76505
+ if(ic.opts['slab'] === 'yes') {
76506
+ if(bInstance) {
76507
+ window.cam.near = 0.1;
76508
+ }
76509
+ else if(window.camMaxDFactorFog !== undefined) {
76510
+ window.cam.near = maxD * window.camMaxDFactorFog - 10; // keep some surrounding residues
76511
+ }
76512
+ else {
76513
+ window.cam.near = maxD * window.camMaxDFactor;
76514
+ }
76515
+ }
76516
+ else {
76517
+ window.cam.near = 0.1;
76518
+ }
76519
+ }
76520
+ // else if (window.cam === ic.orthographicCamera){
76521
+ else if(ic.opts.camera.toLowerCase() == 'orthographic') {
76522
+ if(ic.opts['slab'] === 'yes') {
76523
+ window.cam.near = ic.maxD * 2;
76524
+ }
76525
+ else {
76526
+ window.cam.near = 0;
76527
+ }
76528
+
76529
+ window.cam.far = 10000;
76530
+ }
76531
+
76532
+ window.cam.updateProjectionMatrix();
76533
+ }
76534
+ // else {
76535
+ // also set its own camera for picking purpose
76536
+
76537
+ let maxD = ic.maxD;
76538
+
76539
+ // if(ic.cam === ic.perspectiveCamera) {
76540
+ if(ic.opts.camera.toLowerCase() == 'perspective') {
76541
+ let bInstance = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > ic.maxatomcnt) ? true : false;
76542
+
76543
+ if(ic.opts['slab'] === 'yes') {
76544
+ if(bInstance) {
76545
+ ic.cam.near = 0.1;
76546
+ }
76547
+ else if(ic.camMaxDFactorFog !== undefined) {
76548
+ ic.cam.near = maxD * ic.camMaxDFactorFog - 10; // keep some surrounding residues
76549
+ }
76550
+ else {
76551
+ ic.cam.near = maxD * ic.camMaxDFactor;
76552
+ }
76553
+ }
76554
+ else {
76555
+ ic.cam.near = 0.1;
76556
+ }
76557
+ }
76558
+ // else if (ic.cam === ic.orthographicCamera){
76559
+ else if(ic.opts.camera.toLowerCase() == 'orthographic') {
76560
+ if(ic.opts['slab'] === 'yes') {
76561
+ ic.cam.near = ic.maxD * 2;
76562
+ }
76563
+ else {
76564
+ ic.cam.near = 0;
76565
+ }
76566
+
76567
+ ic.cam.far = 10000;
76568
+ }
76569
+
76570
+ // ic.cam.add(ic.directionalLight);
76571
+
76572
+ ic.cam.updateProjectionMatrix();
76573
+ // }
76574
+ }
76487
76575
  }
76488
76576
 
76489
76577
  /**
@@ -92620,7 +92708,7 @@ class AnnoSnpClinVar {
92620
92708
  let snpResn = snpStr.substr(posSymbol - 1, 1);
92621
92709
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + realResi]);
92622
92710
  let oneLetterRes = (atom) ? me.utilsCls.residueName2Abbr(atom.resn.substr(0, 3)) : '';
92623
- if(!bFromClinVarDb) {
92711
+ if(!bFromClinVarDb && ic.chainsSeq[chnid][resi - 1]) {
92624
92712
  oneLetterRes = ic.chainsSeq[chnid][resi - 1].name;
92625
92713
  }
92626
92714
 
@@ -105492,11 +105580,14 @@ class MmcifParser {
105492
105580
  let mat4 = new Matrix4$1();
105493
105581
  mat4.fromArray(data.assembly[i]);
105494
105582
 
105495
- ic.biomtMatrices[i] = mat4;
105583
+ // sometimes an extra matrix as included, e.g., PDb ID 2GTL
105584
+ if(i == 0 && data.assembly[i][0] != 1) continue;
105585
+
105586
+ ic.biomtMatrices.push(mat4);
105496
105587
  }
105497
105588
 
105498
105589
  ic.asuCnt = ic.biomtMatrices.length;
105499
-
105590
+
105500
105591
  // show bioassembly
105501
105592
  if(me.cfg.bu == 1 && Object.keys(ic.atoms).length * ic.asuCnt > ic.maxatomcnt) {
105502
105593
  ic.bAssembly = true;
@@ -118749,19 +118840,7 @@ class LoadScript {
118749
118840
  updateTransformation(steps) { let ic = this.icn3d; ic.icn3dui;
118750
118841
  let commandTransformation = (ic.commands[steps-1]) ? ic.commands[steps-1].split('|||') : [];
118751
118842
 
118752
- if(commandTransformation.length == 2) {
118753
- let transformation = JSON.parse(commandTransformation[1]);
118754
-
118755
- ic._zoomFactor = transformation.factor;
118756
-
118757
- ic.mouseChange.x = transformation.mouseChange.x;
118758
- ic.mouseChange.y = transformation.mouseChange.y;
118759
-
118760
- ic.quaternion._x = transformation.quaternion._x;
118761
- ic.quaternion._y = transformation.quaternion._y;
118762
- ic.quaternion._z = transformation.quaternion._z;
118763
- ic.quaternion._w = transformation.quaternion._w;
118764
- }
118843
+ ic.transformCls.resetOrientation_base(commandTransformation);
118765
118844
 
118766
118845
  // ic.bRender = true;
118767
118846
  ic.drawCls.draw();
@@ -119543,19 +119622,17 @@ class LoadScript {
119543
119622
 
119544
119623
  let commandTransformation = (ic.commands[steps-1]) ? ic.commands[steps-1].split('|||') : [];
119545
119624
 
119546
- if(commandTransformation.length == 2) {
119547
- let transformation = JSON.parse(commandTransformation[1]);
119625
+ // load a URL with trackball transformation, or no info after "|||"
119626
+ if(commandTransformation.length != 2 || (commandTransformation.length == 2 && commandTransformation[1].substr(0,1) == '{')) {
119627
+ ic.bSetCamera = true;
119628
+ }
119629
+ else {
119630
+ ic.bSetCamera = false;
119631
+ }
119548
119632
 
119549
- ic._zoomFactor = transformation.factor;
119633
+ if(commandTransformation.length == 2 && commandTransformation[1].substr(0,1) == '{') ic.bTransformation = true;
119550
119634
 
119551
- ic.mouseChange.x = transformation.mouseChange.x;
119552
- ic.mouseChange.y = transformation.mouseChange.y;
119553
-
119554
- ic.quaternion._x = transformation.quaternion._x;
119555
- ic.quaternion._y = transformation.quaternion._y;
119556
- ic.quaternion._z = transformation.quaternion._z;
119557
- ic.quaternion._w = transformation.quaternion._w;
119558
- }
119635
+ ic.transformCls.resetOrientation_base(commandTransformation);
119559
119636
 
119560
119637
  ic.selectionCls.oneStructurePerWindow();
119561
119638
 
@@ -127957,13 +128034,9 @@ class Transform {
127957
128034
  this.icn3d = icn3d;
127958
128035
  }
127959
128036
 
127960
- //Set the orientation to the original one, but leave the style, color, etc alone.
127961
- resetOrientation() { let ic = this.icn3d; ic.icn3dui;
127962
- let bSet = false;
127963
- if(ic.commands.length > 0) {
127964
- let commandTransformation = ic.commands[0].split('|||');
127965
-
127966
- if(commandTransformation.length == 2) {
128037
+ resetOrientation_base(commandTransformation) { let ic = this.icn3d; ic.icn3dui;
128038
+ if(commandTransformation.length == 2 && commandTransformation[1].length > 0) {
128039
+ if(ic.bSetCamera) { // |||{"factor"...}
127967
128040
  let transformation = JSON.parse(commandTransformation[1]);
127968
128041
 
127969
128042
  ic._zoomFactor = transformation.factor;
@@ -127975,16 +128048,46 @@ class Transform {
127975
128048
  ic.quaternion._y = transformation.quaternion._y;
127976
128049
  ic.quaternion._z = transformation.quaternion._z;
127977
128050
  ic.quaternion._w = transformation.quaternion._w;
128051
+ bSet1 = true;
128052
+ }
128053
+ else { // |||pos:a,b,c|dir:a,b,c|up:a,b,c|fov:a
128054
+ let bcfArray = commandTransformation[1].split('|');
128055
+ bcfArray.forEach(item => {
128056
+ let itemArray = item.split(':');
128057
+ if(itemArray[0] == 'fov') {
128058
+ ic.cam.fov = parseFloat(itemArray[1]);
128059
+ }
128060
+ else {
128061
+ let abc = itemArray[1].split(',');
128062
+ if(itemArray[0] == 'pos') {
128063
+ ic.cam.position.set(parseFloat(abc[0]), parseFloat(abc[1]), parseFloat(abc[2]));
128064
+ }
128065
+ else if(itemArray[0] == 'dir') {
128066
+ ic.cam.quaternion.setFromUnitVectors(new Vector3$1(0, 0, -1), new Vector3$1(parseFloat(abc[0]), parseFloat(abc[1]), parseFloat(abc[2])));
128067
+ }
128068
+ else if(itemArray[0] == 'up') {
128069
+ ic.cam.up.set(parseFloat(abc[0]), parseFloat(abc[1]), parseFloat(abc[2]));
128070
+ }
128071
+ }
128072
+ });
128073
+
127978
128074
 
127979
- bSet = true;
127980
128075
  }
127981
128076
  }
127982
-
127983
- if(!bSet) {
128077
+ else {
127984
128078
  ic._zoomFactor = 1.0;
127985
128079
  ic.mouseChange = new Vector2$1(0,0);
127986
128080
  ic.quaternion = new Quaternion(0,0,0,1);
127987
128081
  }
128082
+ }
128083
+
128084
+ //Set the orientation to the original one, but leave the style, color, etc alone.
128085
+ resetOrientation() { let ic = this.icn3d; ic.icn3dui;
128086
+ if(ic.commands.length > 0) {
128087
+ let commandTransformation = ic.commands[0].split('|||');
128088
+
128089
+ this.resetOrientation_base(commandTransformation);
128090
+ }
127988
128091
 
127989
128092
  //reset ic.maxD
127990
128093
  ic.maxD = ic.oriMaxD;
@@ -128214,25 +128317,43 @@ class Transform {
128214
128317
  }
128215
128318
 
128216
128319
  getTransformationStr(transformation) {var ic = this.icn3d; ic.icn3dui;
128217
- let transformation2 = {"factor": 1.0, "mouseChange": {"x": 0, "y": 0}, "quaternion": {"_x": 0, "_y": 0, "_z": 0, "_w": 1} };
128218
- transformation2.factor = parseFloat(transformation.factor).toPrecision(4);
128219
- transformation2.mouseChange.x = parseFloat(transformation.mouseChange.x).toPrecision(4);
128220
- transformation2.mouseChange.y = parseFloat(transformation.mouseChange.y).toPrecision(4);
128221
- transformation2.quaternion._x = parseFloat(transformation.quaternion._x).toPrecision(4);
128222
- transformation2.quaternion._y = parseFloat(transformation.quaternion._y).toPrecision(4);
128223
- transformation2.quaternion._z = parseFloat(transformation.quaternion._z).toPrecision(4);
128224
- transformation2.quaternion._w = parseFloat(transformation.quaternion._w).toPrecision(4);
128225
-
128226
- if(transformation2.factor == '1.0000') transformation2.factor = 1;
128227
- if(transformation2.mouseChange.x == '0.0000') transformation2.mouseChange.x = 0;
128228
- if(transformation2.mouseChange.y == '0.0000') transformation2.mouseChange.y = 0;
128229
-
128230
- if(transformation2.quaternion._x == '0.0000') transformation2.quaternion._x = 0;
128231
- if(transformation2.quaternion._y == '0.0000') transformation2.quaternion._y = 0;
128232
- if(transformation2.quaternion._z == '0.0000') transformation2.quaternion._z = 0;
128233
- if(transformation2.quaternion._w == '1.0000') transformation2.quaternion._w = 1;
128234
-
128235
- return JSON.stringify(transformation2);
128320
+ if(ic.bTransformation) {
128321
+ let transformation2 = {"factor": 1.0, "mouseChange": {"x": 0, "y": 0}, "quaternion": {"_x": 0, "_y": 0, "_z": 0, "_w": 1} };
128322
+ transformation2.factor = parseFloat(transformation.factor).toPrecision(4);
128323
+ transformation2.mouseChange.x = parseFloat(transformation.mouseChange.x).toPrecision(4);
128324
+ transformation2.mouseChange.y = parseFloat(transformation.mouseChange.y).toPrecision(4);
128325
+ transformation2.quaternion._x = parseFloat(transformation.quaternion._x).toPrecision(4);
128326
+ transformation2.quaternion._y = parseFloat(transformation.quaternion._y).toPrecision(4);
128327
+ transformation2.quaternion._z = parseFloat(transformation.quaternion._z).toPrecision(4);
128328
+ transformation2.quaternion._w = parseFloat(transformation.quaternion._w).toPrecision(4);
128329
+
128330
+ if(transformation2.factor == '1.0000') transformation2.factor = 1;
128331
+ if(transformation2.mouseChange.x == '0.0000') transformation2.mouseChange.x = 0;
128332
+ if(transformation2.mouseChange.y == '0.0000') transformation2.mouseChange.y = 0;
128333
+
128334
+ if(transformation2.quaternion._x == '0.0000') transformation2.quaternion._x = 0;
128335
+ if(transformation2.quaternion._y == '0.0000') transformation2.quaternion._y = 0;
128336
+ if(transformation2.quaternion._z == '0.0000') transformation2.quaternion._z = 0;
128337
+ if(transformation2.quaternion._w == '1.0000') transformation2.quaternion._w = 1;
128338
+
128339
+ return JSON.stringify(transformation2);
128340
+ }
128341
+ else if(ic.cam) {
128342
+ // |||pos:a,b,c|dir:a,b,c|up:a,b,c|fov:a
128343
+ let str = '';
128344
+ str += 'pos:' + ic.cam.position.x.toPrecision(4) + ',' + ic.cam.position.y.toPrecision(4) + ',' + ic.cam.position.z.toPrecision(4);
128345
+
128346
+ let direction = (new Vector3$1(0, 0, -1)).applyQuaternion(ic.cam.quaternion);
128347
+ str += '|dir:' + direction.x.toPrecision(4) + ',' + direction.y.toPrecision(4) + ',' + direction.z.toPrecision(4);
128348
+
128349
+ str += '|up:' + ic.cam.up.x.toPrecision(4) + ',' + ic.cam.up.y.toPrecision(4) + ',' + ic.cam.up.z.toPrecision(4);
128350
+ str += '|fov:' + ic.cam.fov.toPrecision(4);
128351
+
128352
+ return str;
128353
+ }
128354
+ else {
128355
+ return '';
128356
+ }
128236
128357
  }
128237
128358
  }
128238
128359
 
@@ -131147,38 +131268,14 @@ class Picking {
131147
131268
  else {
131148
131269
  // highlight the sequence background
131149
131270
  ic.hlUpdateCls.updateHlAll();
131150
- let transformation = {};
131151
- transformation.factor = ic._zoomFactor;
131152
- transformation.mouseChange = ic.mouseChange;
131153
- //transformation.quaternion = ic.quaternion;
131154
- transformation.quaternion = {};
131155
- transformation.quaternion._x = parseFloat(ic.quaternion._x).toPrecision(5);
131156
- transformation.quaternion._y = parseFloat(ic.quaternion._y).toPrecision(5);
131157
- transformation.quaternion._z = parseFloat(ic.quaternion._z).toPrecision(5);
131158
- transformation.quaternion._w = parseFloat(ic.quaternion._w).toPrecision(5);
131159
-
131160
- /*
131161
- if(ic.bAddCommands) {
131162
- ic.commands.push('pickatom ' + atom.serial + '|||' + ic.transformCls.getTransformationStr(transformation));
131163
- ic.optsHistory.push(me.hashUtilsCls.cloneHash(ic.opts));
131164
- ic.optsHistory[ic.optsHistory.length - 1].hlatomcount = Object.keys(ic.hAtoms).length;
131165
- if(me.utilsCls.isSessionStorageSupported()) ic.setStyleCls.saveCommandsToSession();
131166
- ic.STATENUMBER = ic.commands.length;
131167
- }
131168
- ic.logs.push('pickatom ' + atom.serial + '(chain: ' + atom.structure + '_' + atom.chain + ', residue: ' + atom.resn + ', number: ' + atom.resi + ', atom: ' + atom.name + ')');
131169
- if( $( "#" + ic.pre + "logtext" ).length ) {
131170
- $("#" + ic.pre + "logtext").val("> " + ic.logs.join("\n> ") + "\n> ").scrollTop($("#" + ic.pre + "logtext")[0].scrollHeight);
131171
- }
131172
- */
131271
+
131173
131272
  me.htmlCls.clickMenuCls.setLogCmd('pickatom ' + atom.serial, true);
131174
131273
 
131175
131274
  ic.selectionCls.saveSelInCommand();
131176
131275
 
131177
131276
  // update the interaction flag
131178
131277
  ic.bSphereCalc = false;
131179
- //me.htmlCls.clickMenuCls.setLogCmd('set calculate sphere false', true);
131180
131278
  ic.bHbondCalc = false;
131181
- //me.htmlCls.clickMenuCls.setLogCmd('set calculate hbond false', true);
131182
131279
  }
131183
131280
  }
131184
131281
  }
@@ -131972,6 +132069,8 @@ class iCn3D {
131972
132069
 
131973
132070
  this.bUsePdbNum = true;
131974
132071
 
132072
+ this.bSetCamera = true;
132073
+
131975
132074
  let bWebGL, bWebGL2, bVR;
131976
132075
  if(!this.icn3dui.bNode) {
131977
132076
  let canvas = document.createElement( 'canvas' );
@@ -132671,10 +132770,10 @@ class iCn3DUI {
132671
132770
  //even when multiple iCn3D viewers are shown together.
132672
132771
  this.pre = this.cfg.divid + "_";
132673
132772
 
132674
- this.REVISION = '3.44.2';
132773
+ this.REVISION = '3.45.0';
132675
132774
 
132676
- // In nodejs, iCn3D defines "window = {navigator: {}}"
132677
- this.bNode = (Object.keys(window).length < 2) ? true : false;
132775
+ // In nodejs, iCn3D defines "window = {navigator: {}}", and added window = {navigator: {}, "__THREE__":"177"}
132776
+ this.bNode = (Object.keys(window).length < 3) ? true : false;
132678
132777
 
132679
132778
  if(this.cfg.command === undefined) this.cfg.command = '';
132680
132779
  if(this.cfg.width === undefined) this.cfg.width = '100%';